@@ -0,0 +1,32 | |||||
|
1 | #ifndef SCIQLOP_DRAGDROPSCROLLER_H | |||
|
2 | #define SCIQLOP_DRAGDROPSCROLLER_H | |||
|
3 | ||||
|
4 | #include <Common/spimpl.h> | |||
|
5 | #include <QScrollArea> | |||
|
6 | ||||
|
7 | /** | |||
|
8 | * @brief Event filter class which manage the scroll of QScrollArea during a drag&drop operation. | |||
|
9 | * @note A QScrollArea inside an other QScrollArea is not fully supported. | |||
|
10 | */ | |||
|
11 | class DragDropScroller : public QObject { | |||
|
12 | Q_OBJECT | |||
|
13 | ||||
|
14 | public: | |||
|
15 | DragDropScroller(QObject *parent = nullptr); | |||
|
16 | ||||
|
17 | void addScrollArea(QScrollArea *scrollArea); | |||
|
18 | void removeScrollArea(QScrollArea *scrollArea); | |||
|
19 | ||||
|
20 | protected: | |||
|
21 | bool eventFilter(QObject *obj, QEvent *event); | |||
|
22 | ||||
|
23 | private: | |||
|
24 | class DragDropScrollerPrivate; | |||
|
25 | spimpl::unique_impl_ptr<DragDropScrollerPrivate> impl; | |||
|
26 | ||||
|
27 | private slots: | |||
|
28 | void onTimer(); | |||
|
29 | }; | |||
|
30 | ||||
|
31 | ||||
|
32 | #endif // SCIQLOP_DRAGDROPSCROLLER_H |
@@ -0,0 +1,125 | |||||
|
1 | #include "DragAndDrop/DragDropScroller.h" | |||
|
2 | ||||
|
3 | #include <QDragEnterEvent> | |||
|
4 | #include <QDragMoveEvent> | |||
|
5 | #include <QScrollBar> | |||
|
6 | #include <QTimer> | |||
|
7 | ||||
|
8 | const int SCROLL_SPEED = 5; | |||
|
9 | const int SCROLL_ZONE_SIZE = 50; | |||
|
10 | ||||
|
11 | struct DragDropScroller::DragDropScrollerPrivate { | |||
|
12 | ||||
|
13 | QList<QScrollArea *> m_ScrollAreas; | |||
|
14 | QScrollArea *m_CurrentScrollArea = nullptr; | |||
|
15 | std::unique_ptr<QTimer> m_Timer = nullptr; | |||
|
16 | ||||
|
17 | enum class ScrollDirection { up, down, unknown }; | |||
|
18 | ScrollDirection m_Direction = ScrollDirection::unknown; | |||
|
19 | ||||
|
20 | explicit DragDropScrollerPrivate() : m_Timer{std::make_unique<QTimer>()} | |||
|
21 | { | |||
|
22 | m_Timer->setInterval(0); | |||
|
23 | } | |||
|
24 | }; | |||
|
25 | ||||
|
26 | DragDropScroller::DragDropScroller(QObject *parent) | |||
|
27 | : QObject{parent}, impl{spimpl::make_unique_impl<DragDropScrollerPrivate>()} | |||
|
28 | { | |||
|
29 | connect(impl->m_Timer.get(), &QTimer::timeout, this, &DragDropScroller::onTimer); | |||
|
30 | } | |||
|
31 | ||||
|
32 | void DragDropScroller::addScrollArea(QScrollArea *scrollArea) | |||
|
33 | { | |||
|
34 | impl->m_ScrollAreas << scrollArea; | |||
|
35 | scrollArea->viewport()->setAcceptDrops(true); | |||
|
36 | } | |||
|
37 | ||||
|
38 | void DragDropScroller::removeScrollArea(QScrollArea *scrollArea) | |||
|
39 | { | |||
|
40 | impl->m_ScrollAreas.removeAll(scrollArea); | |||
|
41 | scrollArea->viewport()->setAcceptDrops(false); | |||
|
42 | } | |||
|
43 | ||||
|
44 | bool DragDropScroller::eventFilter(QObject *obj, QEvent *event) | |||
|
45 | { | |||
|
46 | if (event->type() == QEvent::DragMove) { | |||
|
47 | auto w = static_cast<QWidget *>(obj); | |||
|
48 | ||||
|
49 | if (impl->m_CurrentScrollArea && impl->m_CurrentScrollArea->isAncestorOf(w)) { | |||
|
50 | auto moveEvent = static_cast<QDragMoveEvent *>(event); | |||
|
51 | ||||
|
52 | auto pos = moveEvent->pos(); | |||
|
53 | if (impl->m_CurrentScrollArea->viewport() != w) { | |||
|
54 | auto globalPos = w->mapToGlobal(moveEvent->pos()); | |||
|
55 | pos = impl->m_CurrentScrollArea->viewport()->mapFromGlobal(globalPos); | |||
|
56 | } | |||
|
57 | ||||
|
58 | auto isInTopZone = pos.y() > impl->m_CurrentScrollArea->viewport()->size().height() | |||
|
59 | - SCROLL_ZONE_SIZE; | |||
|
60 | auto isInBottomZone = pos.y() < SCROLL_ZONE_SIZE; | |||
|
61 | ||||
|
62 | if (!isInTopZone && !isInBottomZone) { | |||
|
63 | impl->m_Direction = DragDropScrollerPrivate::ScrollDirection::unknown; | |||
|
64 | impl->m_Timer->stop(); | |||
|
65 | } | |||
|
66 | else if (!impl->m_Timer->isActive()) { | |||
|
67 | impl->m_Direction = isInTopZone ? DragDropScrollerPrivate::ScrollDirection::up | |||
|
68 | : DragDropScrollerPrivate::ScrollDirection::down; | |||
|
69 | impl->m_Timer->start(); | |||
|
70 | } | |||
|
71 | } | |||
|
72 | } | |||
|
73 | else if (event->type() == QEvent::DragEnter) { | |||
|
74 | auto w = static_cast<QWidget *>(obj); | |||
|
75 | ||||
|
76 | for (auto scrollArea : impl->m_ScrollAreas) { | |||
|
77 | if (impl->m_CurrentScrollArea != scrollArea && scrollArea->isAncestorOf(w)) { | |||
|
78 | auto enterEvent = static_cast<QDragEnterEvent *>(event); | |||
|
79 | enterEvent->acceptProposedAction(); | |||
|
80 | enterEvent->setDropAction(Qt::IgnoreAction); | |||
|
81 | impl->m_CurrentScrollArea = scrollArea; | |||
|
82 | break; | |||
|
83 | } | |||
|
84 | } | |||
|
85 | } | |||
|
86 | else if (event->type() == QEvent::DragLeave) { | |||
|
87 | if (impl->m_CurrentScrollArea) { | |||
|
88 | if (!QRect(QPoint(), impl->m_CurrentScrollArea->size()) | |||
|
89 | .contains(impl->m_CurrentScrollArea->mapFromGlobal(QCursor::pos()))) { | |||
|
90 | impl->m_CurrentScrollArea = nullptr; | |||
|
91 | impl->m_Direction = DragDropScrollerPrivate::ScrollDirection::unknown; | |||
|
92 | impl->m_Timer->stop(); | |||
|
93 | } | |||
|
94 | } | |||
|
95 | } | |||
|
96 | else if (event->type() == QEvent::Drop) { | |||
|
97 | if (impl->m_CurrentScrollArea) { | |||
|
98 | impl->m_CurrentScrollArea = nullptr; | |||
|
99 | impl->m_Direction = DragDropScrollerPrivate::ScrollDirection::unknown; | |||
|
100 | impl->m_Timer->stop(); | |||
|
101 | } | |||
|
102 | } | |||
|
103 | ||||
|
104 | return false; | |||
|
105 | } | |||
|
106 | ||||
|
107 | void DragDropScroller::onTimer() | |||
|
108 | { | |||
|
109 | if (impl->m_CurrentScrollArea) { | |||
|
110 | auto mvt = 0; | |||
|
111 | switch (impl->m_Direction) { | |||
|
112 | case DragDropScrollerPrivate::ScrollDirection::up: | |||
|
113 | mvt = SCROLL_SPEED; | |||
|
114 | break; | |||
|
115 | case DragDropScrollerPrivate::ScrollDirection::down: | |||
|
116 | mvt = -SCROLL_SPEED; | |||
|
117 | break; | |||
|
118 | default: | |||
|
119 | break; | |||
|
120 | } | |||
|
121 | ||||
|
122 | impl->m_CurrentScrollArea->verticalScrollBar()->setValue( | |||
|
123 | impl->m_CurrentScrollArea->verticalScrollBar()->value() + mvt); | |||
|
124 | } | |||
|
125 | } |
@@ -64,28 +64,4 private: | |||||
64 | spimpl::unique_impl_ptr<DragDropHelperPrivate> impl; |
|
64 | spimpl::unique_impl_ptr<DragDropHelperPrivate> impl; | |
65 | }; |
|
65 | }; | |
66 |
|
66 | |||
67 | /** |
|
|||
68 | * @brief Event filter class which manage the scroll of QScrollArea during a drag&drop operation. |
|
|||
69 | * @note A QScrollArea inside an other QScrollArea is not fully supported. |
|
|||
70 | */ |
|
|||
71 | class DragDropScroller : public QObject { |
|
|||
72 | Q_OBJECT |
|
|||
73 |
|
||||
74 | public: |
|
|||
75 | DragDropScroller(QObject *parent = nullptr); |
|
|||
76 |
|
||||
77 | void addScrollArea(QScrollArea *scrollArea); |
|
|||
78 | void removeScrollArea(QScrollArea *scrollArea); |
|
|||
79 |
|
||||
80 | protected: |
|
|||
81 | bool eventFilter(QObject *obj, QEvent *event); |
|
|||
82 |
|
||||
83 | private: |
|
|||
84 | class DragDropScrollerPrivate; |
|
|||
85 | spimpl::unique_impl_ptr<DragDropScrollerPrivate> impl; |
|
|||
86 |
|
||||
87 | private slots: |
|
|||
88 | void onTimer(); |
|
|||
89 | }; |
|
|||
90 |
|
||||
91 | #endif // SCIQLOP_DRAGDROPHELPER_H |
|
67 | #endif // SCIQLOP_DRAGDROPHELPER_H |
@@ -7,6 +7,7 gui_moc_headers = [ | |||||
7 | 'include/SidePane/SqpSidePane.h', |
|
7 | 'include/SidePane/SqpSidePane.h', | |
8 | 'include/SqpApplication.h', |
|
8 | 'include/SqpApplication.h', | |
9 | 'include/DragAndDrop/DragDropHelper.h', |
|
9 | 'include/DragAndDrop/DragDropHelper.h', | |
|
10 | 'include/DragAndDrop/DragDropScroller.h', | |||
10 | 'include/TimeWidget/TimeWidget.h', |
|
11 | 'include/TimeWidget/TimeWidget.h', | |
11 | 'include/Variable/VariableInspectorWidget.h', |
|
12 | 'include/Variable/VariableInspectorWidget.h', | |
12 | 'include/Variable/VariableInspectorTableView.h', |
|
13 | 'include/Variable/VariableInspectorTableView.h', | |
@@ -44,6 +45,7 gui_moc_files = qt5.preprocess(moc_headers : gui_moc_headers, | |||||
44 | gui_sources = [ |
|
45 | gui_sources = [ | |
45 | 'src/SqpApplication.cpp', |
|
46 | 'src/SqpApplication.cpp', | |
46 | 'src/DragAndDrop/DragDropHelper.cpp', |
|
47 | 'src/DragAndDrop/DragDropHelper.cpp', | |
|
48 | 'src/DragAndDrop/DragDropScroller.cpp', | |||
47 | 'src/Common/ColorUtils.cpp', |
|
49 | 'src/Common/ColorUtils.cpp', | |
48 | 'src/Common/VisualizationDef.cpp', |
|
50 | 'src/Common/VisualizationDef.cpp', | |
49 | 'src/DataSource/DataSourceTreeWidgetItem.cpp', |
|
51 | 'src/DataSource/DataSourceTreeWidgetItem.cpp', |
@@ -1,4 +1,5 | |||||
1 | #include "DragAndDrop/DragDropHelper.h" |
|
1 | #include "DragAndDrop/DragDropHelper.h" | |
|
2 | #include "DragAndDrop/DragDropScroller.h" | |||
2 | #include "SqpApplication.h" |
|
3 | #include "SqpApplication.h" | |
3 | #include "Visualization/VisualizationDragDropContainer.h" |
|
4 | #include "Visualization/VisualizationDragDropContainer.h" | |
4 | #include "Visualization/VisualizationDragWidget.h" |
|
5 | #include "Visualization/VisualizationDragWidget.h" | |
@@ -12,134 +13,13 | |||||
12 | #include "Common/VisualizationDef.h" |
|
13 | #include "Common/VisualizationDef.h" | |
13 |
|
14 | |||
14 | #include <QDir> |
|
15 | #include <QDir> | |
15 | #include <QDragEnterEvent> |
|
|||
16 | #include <QDragMoveEvent> |
|
|||
17 | #include <QLabel> |
|
16 | #include <QLabel> | |
18 |
#include <Q |
|
17 | #include <QUrl> | |
19 | #include <QScrollBar> |
|
|||
20 | #include <QTimer> |
|
|||
21 | #include <QVBoxLayout> |
|
18 | #include <QVBoxLayout> | |
22 |
|
19 | |||
23 | const int SCROLL_SPEED = 5; |
|
|||
24 | const int SCROLL_ZONE_SIZE = 50; |
|
|||
25 |
|
20 | |||
26 | Q_LOGGING_CATEGORY(LOG_DragDropHelper, "DragDrophelper") |
|
21 | Q_LOGGING_CATEGORY(LOG_DragDropHelper, "DragDrophelper") | |
27 |
|
22 | |||
28 | struct DragDropScroller::DragDropScrollerPrivate { |
|
|||
29 |
|
||||
30 | QList<QScrollArea *> m_ScrollAreas; |
|
|||
31 | QScrollArea *m_CurrentScrollArea = nullptr; |
|
|||
32 | std::unique_ptr<QTimer> m_Timer = nullptr; |
|
|||
33 |
|
||||
34 | enum class ScrollDirection { up, down, unknown }; |
|
|||
35 | ScrollDirection m_Direction = ScrollDirection::unknown; |
|
|||
36 |
|
||||
37 | explicit DragDropScrollerPrivate() : m_Timer{std::make_unique<QTimer>()} |
|
|||
38 | { |
|
|||
39 | m_Timer->setInterval(0); |
|
|||
40 | } |
|
|||
41 | }; |
|
|||
42 |
|
||||
43 | DragDropScroller::DragDropScroller(QObject *parent) |
|
|||
44 | : QObject{parent}, impl{spimpl::make_unique_impl<DragDropScrollerPrivate>()} |
|
|||
45 | { |
|
|||
46 | connect(impl->m_Timer.get(), &QTimer::timeout, this, &DragDropScroller::onTimer); |
|
|||
47 | } |
|
|||
48 |
|
||||
49 | void DragDropScroller::addScrollArea(QScrollArea *scrollArea) |
|
|||
50 | { |
|
|||
51 | impl->m_ScrollAreas << scrollArea; |
|
|||
52 | scrollArea->viewport()->setAcceptDrops(true); |
|
|||
53 | } |
|
|||
54 |
|
||||
55 | void DragDropScroller::removeScrollArea(QScrollArea *scrollArea) |
|
|||
56 | { |
|
|||
57 | impl->m_ScrollAreas.removeAll(scrollArea); |
|
|||
58 | scrollArea->viewport()->setAcceptDrops(false); |
|
|||
59 | } |
|
|||
60 |
|
||||
61 | bool DragDropScroller::eventFilter(QObject *obj, QEvent *event) |
|
|||
62 | { |
|
|||
63 | if (event->type() == QEvent::DragMove) { |
|
|||
64 | auto w = static_cast<QWidget *>(obj); |
|
|||
65 |
|
||||
66 | if (impl->m_CurrentScrollArea && impl->m_CurrentScrollArea->isAncestorOf(w)) { |
|
|||
67 | auto moveEvent = static_cast<QDragMoveEvent *>(event); |
|
|||
68 |
|
||||
69 | auto pos = moveEvent->pos(); |
|
|||
70 | if (impl->m_CurrentScrollArea->viewport() != w) { |
|
|||
71 | auto globalPos = w->mapToGlobal(moveEvent->pos()); |
|
|||
72 | pos = impl->m_CurrentScrollArea->viewport()->mapFromGlobal(globalPos); |
|
|||
73 | } |
|
|||
74 |
|
||||
75 | auto isInTopZone = pos.y() > impl->m_CurrentScrollArea->viewport()->size().height() |
|
|||
76 | - SCROLL_ZONE_SIZE; |
|
|||
77 | auto isInBottomZone = pos.y() < SCROLL_ZONE_SIZE; |
|
|||
78 |
|
||||
79 | if (!isInTopZone && !isInBottomZone) { |
|
|||
80 | impl->m_Direction = DragDropScrollerPrivate::ScrollDirection::unknown; |
|
|||
81 | impl->m_Timer->stop(); |
|
|||
82 | } |
|
|||
83 | else if (!impl->m_Timer->isActive()) { |
|
|||
84 | impl->m_Direction = isInTopZone ? DragDropScrollerPrivate::ScrollDirection::up |
|
|||
85 | : DragDropScrollerPrivate::ScrollDirection::down; |
|
|||
86 | impl->m_Timer->start(); |
|
|||
87 | } |
|
|||
88 | } |
|
|||
89 | } |
|
|||
90 | else if (event->type() == QEvent::DragEnter) { |
|
|||
91 | auto w = static_cast<QWidget *>(obj); |
|
|||
92 |
|
||||
93 | for (auto scrollArea : impl->m_ScrollAreas) { |
|
|||
94 | if (impl->m_CurrentScrollArea != scrollArea && scrollArea->isAncestorOf(w)) { |
|
|||
95 | auto enterEvent = static_cast<QDragEnterEvent *>(event); |
|
|||
96 | enterEvent->acceptProposedAction(); |
|
|||
97 | enterEvent->setDropAction(Qt::IgnoreAction); |
|
|||
98 | impl->m_CurrentScrollArea = scrollArea; |
|
|||
99 | break; |
|
|||
100 | } |
|
|||
101 | } |
|
|||
102 | } |
|
|||
103 | else if (event->type() == QEvent::DragLeave) { |
|
|||
104 | if (impl->m_CurrentScrollArea) { |
|
|||
105 | if (!QRect(QPoint(), impl->m_CurrentScrollArea->size()) |
|
|||
106 | .contains(impl->m_CurrentScrollArea->mapFromGlobal(QCursor::pos()))) { |
|
|||
107 | impl->m_CurrentScrollArea = nullptr; |
|
|||
108 | impl->m_Direction = DragDropScrollerPrivate::ScrollDirection::unknown; |
|
|||
109 | impl->m_Timer->stop(); |
|
|||
110 | } |
|
|||
111 | } |
|
|||
112 | } |
|
|||
113 | else if (event->type() == QEvent::Drop) { |
|
|||
114 | if (impl->m_CurrentScrollArea) { |
|
|||
115 | impl->m_CurrentScrollArea = nullptr; |
|
|||
116 | impl->m_Direction = DragDropScrollerPrivate::ScrollDirection::unknown; |
|
|||
117 | impl->m_Timer->stop(); |
|
|||
118 | } |
|
|||
119 | } |
|
|||
120 |
|
||||
121 | return false; |
|
|||
122 | } |
|
|||
123 |
|
||||
124 | void DragDropScroller::onTimer() |
|
|||
125 | { |
|
|||
126 | if (impl->m_CurrentScrollArea) { |
|
|||
127 | auto mvt = 0; |
|
|||
128 | switch (impl->m_Direction) { |
|
|||
129 | case DragDropScrollerPrivate::ScrollDirection::up: |
|
|||
130 | mvt = SCROLL_SPEED; |
|
|||
131 | break; |
|
|||
132 | case DragDropScrollerPrivate::ScrollDirection::down: |
|
|||
133 | mvt = -SCROLL_SPEED; |
|
|||
134 | break; |
|
|||
135 | default: |
|
|||
136 | break; |
|
|||
137 | } |
|
|||
138 |
|
||||
139 | impl->m_CurrentScrollArea->verticalScrollBar()->setValue( |
|
|||
140 | impl->m_CurrentScrollArea->verticalScrollBar()->value() + mvt); |
|
|||
141 | } |
|
|||
142 | } |
|
|||
143 |
|
23 | |||
144 | struct DragDropHelper::DragDropHelperPrivate { |
|
24 | struct DragDropHelper::DragDropHelperPrivate { | |
145 |
|
25 |
General Comments 0
You need to be logged in to leave comments.
Login now