Auto status change to "Under Review"
@@ -53,6 +53,8 public: | |||
|
53 | 53 | |
|
54 | 54 | QUrl imageTemporaryUrl(const QImage &image) const; |
|
55 | 55 | |
|
56 | void setHightlightedDragWidget(VisualizationDragWidget *dragWidget); | |
|
57 | ||
|
56 | 58 | private: |
|
57 | 59 | class DragDropHelperPrivate; |
|
58 | 60 | spimpl::unique_impl_ptr<DragDropHelperPrivate> impl; |
@@ -13,6 +13,7 public: | |||
|
13 | 13 | |
|
14 | 14 | virtual QMimeData *mimeData() const = 0; |
|
15 | 15 | virtual bool isDragAllowed() const = 0; |
|
16 | virtual void highlightForMerge(bool highlighted) { Q_UNUSED(highlighted); }; | |
|
16 | 17 | |
|
17 | 18 | protected: |
|
18 | 19 | virtual void mousePressEvent(QMouseEvent *event) override; |
@@ -59,6 +59,7 public: | |||
|
59 | 59 | // VisualisationDragWidget |
|
60 | 60 | QMimeData *mimeData() const override; |
|
61 | 61 | bool isDragAllowed() const override; |
|
62 | void highlightForMerge(bool highlighted) override; | |
|
62 | 63 | |
|
63 | 64 | signals: |
|
64 | 65 | void synchronize(const SqpRange &range, const SqpRange &oldRange); |
@@ -29,7 +29,6 struct DragDropScroller::DragDropScrollerPrivate { | |||
|
29 | 29 | QScrollArea *m_CurrentScrollArea = nullptr; |
|
30 | 30 | std::unique_ptr<QTimer> m_Timer = nullptr; |
|
31 | 31 | |
|
32 | ||
|
33 | 32 | enum class ScrollDirection { up, down, unknown }; |
|
34 | 33 | ScrollDirection m_Direction = ScrollDirection::unknown; |
|
35 | 34 | |
@@ -148,6 +147,8 struct DragDropHelper::DragDropHelperPrivate { | |||
|
148 | 147 | QString m_ImageTempUrl; // Temporary file for image url generated by the drag & drop. Not using |
|
149 | 148 | // QTemporaryFile to have a name which is not generated. |
|
150 | 149 | |
|
150 | VisualizationDragWidget *m_HighlightedDragWidget = nullptr; | |
|
151 | ||
|
151 | 152 | explicit DragDropHelperPrivate() |
|
152 | 153 | : m_PlaceHolder{std::make_unique<QWidget>()}, |
|
153 | 154 | m_DragDropScroller{std::make_unique<DragDropScroller>()} |
@@ -188,6 +189,7 DragDropHelper::~DragDropHelper() | |||
|
188 | 189 | void DragDropHelper::resetDragAndDrop() |
|
189 | 190 | { |
|
190 | 191 | setCurrentDragWidget(nullptr); |
|
192 | impl->m_HighlightedDragWidget = nullptr; | |
|
191 | 193 | } |
|
192 | 194 | |
|
193 | 195 | void DragDropHelper::setCurrentDragWidget(VisualizationDragWidget *dragWidget) |
@@ -245,6 +247,18 QUrl DragDropHelper::imageTemporaryUrl(const QImage &image) const | |||
|
245 | 247 | return QUrl::fromLocalFile(impl->m_ImageTempUrl); |
|
246 | 248 | } |
|
247 | 249 | |
|
250 | void DragDropHelper::setHightlightedDragWidget(VisualizationDragWidget *dragWidget) | |
|
251 | { | |
|
252 | if (impl->m_HighlightedDragWidget) { | |
|
253 | impl->m_HighlightedDragWidget->highlightForMerge(false); | |
|
254 | } | |
|
255 | ||
|
256 | if (dragWidget) { | |
|
257 | impl->m_HighlightedDragWidget = dragWidget; | |
|
258 | impl->m_HighlightedDragWidget->highlightForMerge(true); | |
|
259 | } | |
|
260 | } | |
|
261 | ||
|
248 | 262 | bool DragDropHelper::checkMimeDataForVisualization(const QMimeData *mimeData, |
|
249 | 263 | VisualizationDragDropContainer *dropContainer) |
|
250 | 264 | { |
@@ -21,6 +21,7 struct VisualizationDragDropContainer::VisualizationDragDropContainerPrivate { | |||
|
21 | 21 | QStringList m_MergeAllowedMimeTypes; |
|
22 | 22 | VisualizationDragDropContainer::AcceptMimeDataFunction m_AcceptMimeDataFun |
|
23 | 23 | = [](auto mimeData) { return true; }; |
|
24 | int m_MinContainerHeight = 0; | |
|
24 | 25 | |
|
25 | 26 | explicit VisualizationDragDropContainerPrivate(QWidget *widget) |
|
26 | 27 | { |
@@ -55,7 +56,7 struct VisualizationDragDropContainer::VisualizationDragDropContainerPrivate { | |||
|
55 | 56 | return sqpApp->dragDropHelper().placeHolder().parentWidget() == m_Layout->parentWidget(); |
|
56 | 57 | } |
|
57 | 58 | |
|
58 | VisualizationDragWidget *getChildDragWidgetAt(QWidget *parent, const QPoint &pos) const | |
|
59 | VisualizationDragWidget *getChildDragWidgetAt(const QWidget *parent, const QPoint &pos) const | |
|
59 | 60 | { |
|
60 | 61 | VisualizationDragWidget *dragWidget = nullptr; |
|
61 | 62 | |
@@ -79,6 +80,21 struct VisualizationDragDropContainer::VisualizationDragDropContainerPrivate { | |||
|
79 | 80 | .adjusted(adustNum, adustNum, -adustNum, -adustNum); |
|
80 | 81 | return containerRect.contains(container->mapFromGlobal(QCursor::pos())); |
|
81 | 82 | } |
|
83 | ||
|
84 | int countDragWidget(const QWidget *parent) const | |
|
85 | { | |
|
86 | auto nbGraph = 0; | |
|
87 | for (auto child : parent->children()) { | |
|
88 | if (qobject_cast<VisualizationDragWidget *>(child)) { | |
|
89 | nbGraph += 1; | |
|
90 | } | |
|
91 | } | |
|
92 | ||
|
93 | return nbGraph; | |
|
94 | } | |
|
95 | ||
|
96 | void findPlaceHolderPosition(const QPoint &pos, bool canMerge, | |
|
97 | const VisualizationDragDropContainer *container); | |
|
82 | 98 | }; |
|
83 | 99 | |
|
84 | 100 | VisualizationDragDropContainer::VisualizationDragDropContainer(QWidget *parent) |
@@ -117,14 +133,7 void VisualizationDragDropContainer::setMergeAllowedMimeTypes(const QStringList | |||
|
117 | 133 | |
|
118 | 134 | int VisualizationDragDropContainer::countDragWidget() const |
|
119 | 135 | { |
|
120 | auto nbGraph = 0; | |
|
121 | for (auto child : children()) { | |
|
122 | if (qobject_cast<VisualizationDragWidget *>(child)) { | |
|
123 | nbGraph += 1; | |
|
124 | } | |
|
125 | } | |
|
126 | ||
|
127 | return nbGraph; | |
|
136 | return impl->countDragWidget(this); | |
|
128 | 137 | } |
|
129 | 138 | |
|
130 | 139 | void VisualizationDragDropContainer::setAcceptMimeDataFunction( |
@@ -185,7 +194,7 void VisualizationDragDropContainer::dragEnterEvent(QDragEnterEvent *event) | |||
|
185 | 194 | |
|
186 | 195 | if (dragWidget) { |
|
187 | 196 | // If the drag&drop is internal to the visualization, entering the container hide |
|
188 |
// the dragWidget which was |
|
|
197 | // the dragWidget which was made visible by the dragLeaveEvent | |
|
189 | 198 | auto parentWidget |
|
190 | 199 | = qobject_cast<VisualizationDragDropContainer *>(dragWidget->parentWidget()); |
|
191 | 200 | if (parentWidget) { |
@@ -193,26 +202,8 void VisualizationDragDropContainer::dragEnterEvent(QDragEnterEvent *event) | |||
|
193 | 202 | } |
|
194 | 203 | } |
|
195 | 204 | |
|
196 | auto dragWidgetHovered = impl->getChildDragWidgetAt(this, event->pos()); | |
|
197 | ||
|
198 | if (dragWidgetHovered) { | |
|
199 | auto hoveredWidgetIndex = impl->m_Layout->indexOf(dragWidgetHovered); | |
|
200 | ||
|
201 | if (dragWidget) { | |
|
202 | auto dragWidgetIndex = impl->m_Layout->indexOf(helper.getCurrentDragWidget()); | |
|
203 | if (dragWidgetIndex >= 0 && dragWidgetIndex <= hoveredWidgetIndex) { | |
|
204 | // Correction of the index if the drop occurs in the same container | |
|
205 | // and if the drag is started from the visualization (in that case, the | |
|
206 | // dragWidget is hidden) | |
|
207 | hoveredWidgetIndex += 1; | |
|
208 | } | |
|
209 | } | |
|
210 | ||
|
211 | helper.insertPlaceHolder(impl->m_Layout, hoveredWidgetIndex); | |
|
212 | } | |
|
213 | else { | |
|
214 | helper.insertPlaceHolder(impl->m_Layout, 0); | |
|
215 | } | |
|
205 | auto canMerge = impl->allowMergeMimeData(event->mimeData()); | |
|
206 | impl->findPlaceHolderPosition(event->pos(), canMerge, this); | |
|
216 | 207 | } |
|
217 | 208 | else { |
|
218 | 209 | // do nothing |
@@ -233,6 +224,8 void VisualizationDragDropContainer::dragLeaveEvent(QDragLeaveEvent *event) | |||
|
233 | 224 | |
|
234 | 225 | if (!impl->cursorIsInContainer(this)) { |
|
235 | 226 | helper.removePlaceHolder(); |
|
227 | helper.setHightlightedDragWidget(nullptr); | |
|
228 | impl->m_MinContainerHeight = 0; | |
|
236 | 229 | |
|
237 | 230 | auto dragWidget = helper.getCurrentDragWidget(); |
|
238 | 231 | if (dragWidget) { |
@@ -258,60 +251,8 void VisualizationDragDropContainer::dragLeaveEvent(QDragLeaveEvent *event) | |||
|
258 | 251 | void VisualizationDragDropContainer::dragMoveEvent(QDragMoveEvent *event) |
|
259 | 252 | { |
|
260 | 253 | if (impl->acceptMimeData(event->mimeData())) { |
|
261 | auto dragWidgetHovered = impl->getChildDragWidgetAt(this, event->pos()); | |
|
262 | if (dragWidgetHovered) { | |
|
263 | 254 |
|
|
264 | ||
|
265 | auto nbDragWidget = countDragWidget(); | |
|
266 | if (nbDragWidget > 0) { | |
|
267 | auto graphHeight = qMax(size().height() / nbDragWidget, GRAPH_MINIMUM_HEIGHT); | |
|
268 | ||
|
269 | auto dropIndex = floor(event->pos().y() / graphHeight); | |
|
270 | auto zoneSize = qMin(graphHeight / 3.0, 150.0); | |
|
271 | ||
|
272 | auto isOnTop = event->pos().y() < dropIndex * graphHeight + zoneSize; | |
|
273 | auto isOnBottom = event->pos().y() > (dropIndex + 1) * graphHeight - zoneSize; | |
|
274 | ||
|
275 | auto &helper = sqpApp->dragDropHelper(); | |
|
276 | auto placeHolderIndex = impl->m_Layout->indexOf(&(helper.placeHolder())); | |
|
277 | ||
|
278 | if (isOnTop || isOnBottom) { | |
|
279 | if (isOnBottom) { | |
|
280 | dropIndex += 1; | |
|
281 | } | |
|
282 | ||
|
283 | if (helper.getCurrentDragWidget()) { | |
|
284 | auto dragWidgetIndex | |
|
285 | = impl->m_Layout->indexOf(helper.getCurrentDragWidget()); | |
|
286 | if (dragWidgetIndex >= 0 && dragWidgetIndex <= dropIndex) { | |
|
287 | // Correction of the index if the drop occurs in the same container | |
|
288 | // and if the drag is started from the visualization (in that case, the | |
|
289 | // dragWidget is hidden) | |
|
290 | dropIndex += 1; | |
|
291 | } | |
|
292 | } | |
|
293 | ||
|
294 | if (dropIndex != placeHolderIndex) { | |
|
295 | helper.insertPlaceHolder(impl->m_Layout, dropIndex); | |
|
296 | } | |
|
297 | } | |
|
298 | else if (canMerge) { | |
|
299 | // drop on the middle -> merge | |
|
300 | if (impl->hasPlaceHolder()) { | |
|
301 | helper.removePlaceHolder(); | |
|
302 | } | |
|
303 | } | |
|
304 | } | |
|
305 | else { | |
|
306 | qCWarning(LOG_VisualizationDragDropContainer()) | |
|
307 | << tr("VisualizationDragDropContainer::dragMoveEvent, no widget found in the " | |
|
308 | "container"); | |
|
309 | } | |
|
310 | } | |
|
311 | else { | |
|
312 | // No hovered drag widget, the mouse is probably hover the placeHolder | |
|
313 | // Do nothing | |
|
314 | } | |
|
255 | impl->findPlaceHolderPosition(event->pos(), canMerge, this); | |
|
315 | 256 | } |
|
316 | 257 | else { |
|
317 | 258 | event->ignore(); |
@@ -351,12 +292,89 void VisualizationDragDropContainer::dropEvent(QDropEvent *event) | |||
|
351 | 292 | qCWarning(LOG_VisualizationDragDropContainer()) |
|
352 | 293 | << tr("VisualizationDragDropContainer::dropEvent, couldn't drop because the " |
|
353 | 294 | "placeHolder is not found."); |
|
354 | Q_ASSERT(false); | |
|
295 | // Q_ASSERT(false); | |
|
355 | 296 | } |
|
356 | 297 | } |
|
357 | 298 | else { |
|
358 | 299 | event->ignore(); |
|
359 | 300 | } |
|
360 | 301 | |
|
302 | sqpApp->dragDropHelper().setHightlightedDragWidget(nullptr); | |
|
303 | impl->m_MinContainerHeight = 0; | |
|
304 | ||
|
361 | 305 | QWidget::dropEvent(event); |
|
362 | 306 | } |
|
307 | ||
|
308 | ||
|
309 | void VisualizationDragDropContainer::VisualizationDragDropContainerPrivate::findPlaceHolderPosition( | |
|
310 | const QPoint &pos, bool canMerge, const VisualizationDragDropContainer *container) | |
|
311 | { | |
|
312 | auto &helper = sqpApp->dragDropHelper(); | |
|
313 | ||
|
314 | auto dragWidgetHovered = getChildDragWidgetAt(container, pos); | |
|
315 | if (dragWidgetHovered) { | |
|
316 | auto nbDragWidget = countDragWidget(container); | |
|
317 | if (nbDragWidget > 0) { | |
|
318 | ||
|
319 | if (m_MinContainerHeight == 0) { | |
|
320 | m_MinContainerHeight = container->size().height(); | |
|
321 | } | |
|
322 | ||
|
323 | m_MinContainerHeight = qMin(m_MinContainerHeight, container->size().height()); | |
|
324 | auto graphHeight = qMax(m_MinContainerHeight / nbDragWidget, GRAPH_MINIMUM_HEIGHT); | |
|
325 | ||
|
326 | auto posY = pos.y(); | |
|
327 | auto dropIndex = floor(posY / graphHeight); | |
|
328 | auto zoneSize = qMin(graphHeight / 4.0, 75.0); | |
|
329 | ||
|
330 | ||
|
331 | auto isOnTop = posY < dropIndex * graphHeight + zoneSize; | |
|
332 | auto isOnBottom = posY > (dropIndex + 1) * graphHeight - zoneSize; | |
|
333 | ||
|
334 | auto placeHolderIndex = m_Layout->indexOf(&(helper.placeHolder())); | |
|
335 | ||
|
336 | if (isOnTop || isOnBottom || !canMerge) { | |
|
337 | if (isOnBottom) { | |
|
338 | dropIndex += 1; | |
|
339 | } | |
|
340 | ||
|
341 | if (helper.getCurrentDragWidget()) { | |
|
342 | auto dragWidgetIndex = m_Layout->indexOf(helper.getCurrentDragWidget()); | |
|
343 | if (dragWidgetIndex >= 0 && dragWidgetIndex <= dropIndex) { | |
|
344 | // Correction of the index if the drop occurs in the same container | |
|
345 | // and if the drag is started from the visualization (in that case, the | |
|
346 | // dragWidget is hidden) | |
|
347 | dropIndex += 1; | |
|
348 | } | |
|
349 | } | |
|
350 | ||
|
351 | if (dropIndex != placeHolderIndex) { | |
|
352 | helper.insertPlaceHolder(m_Layout, dropIndex); | |
|
353 | } | |
|
354 | ||
|
355 | helper.setHightlightedDragWidget(nullptr); | |
|
356 | } | |
|
357 | else if (canMerge) { | |
|
358 | // drop on the middle -> merge | |
|
359 | if (hasPlaceHolder()) { | |
|
360 | helper.removePlaceHolder(); | |
|
361 | } | |
|
362 | ||
|
363 | helper.setHightlightedDragWidget(dragWidgetHovered); | |
|
364 | } | |
|
365 | } | |
|
366 | else { | |
|
367 | qCWarning(LOG_VisualizationDragDropContainer()) | |
|
368 | << tr("VisualizationDragDropContainer::dragMoveEvent, no widget found in the " | |
|
369 | "container"); | |
|
370 | } | |
|
371 | } | |
|
372 | else if (!hasPlaceHolder()) { | |
|
373 | // Drop on an empty container, just add the placeHolder at the top | |
|
374 | helper.insertPlaceHolder(m_Layout, 0); | |
|
375 | } | |
|
376 | else { | |
|
377 | // No hovered drag widget, the mouse is probably hover the placeHolder | |
|
378 | // Do nothing | |
|
379 | } | |
|
380 | } |
@@ -243,6 +243,18 bool VisualizationGraphWidget::isDragAllowed() const | |||
|
243 | 243 | return true; |
|
244 | 244 | } |
|
245 | 245 | |
|
246 | void VisualizationGraphWidget::highlightForMerge(bool highlighted) | |
|
247 | { | |
|
248 | if (highlighted) { | |
|
249 | plot().setBackground(QBrush(QColor("#BBD5EE"))); | |
|
250 | } | |
|
251 | else { | |
|
252 | plot().setBackground(QBrush(Qt::white)); | |
|
253 | } | |
|
254 | ||
|
255 | plot().update(); | |
|
256 | } | |
|
257 | ||
|
246 | 258 | void VisualizationGraphWidget::closeEvent(QCloseEvent *event) |
|
247 | 259 | { |
|
248 | 260 | Q_UNUSED(event); |
@@ -86,6 +86,7 VisualizationZoneWidget::VisualizationZoneWidget(const QString &name, QWidget *p | |||
|
86 | 86 | ui->zoneNameLabel->setText(name); |
|
87 | 87 | |
|
88 | 88 | ui->dragDropContainer->setAcceptedMimeTypes({MIME_TYPE_GRAPH, MIME_TYPE_VARIABLE_LIST}); |
|
89 | ui->dragDropContainer->setMergeAllowedMimeTypes({MIME_TYPE_VARIABLE_LIST}); | |
|
89 | 90 | ui->dragDropContainer->setAcceptMimeDataFunction([this](auto mimeData) { |
|
90 | 91 | return sqpApp->dragDropHelper().checkMimeDataForVisualization(mimeData, |
|
91 | 92 | ui->dragDropContainer); |
General Comments 3
Pull request updated. Auto status change to "Under Review"
Changed commits: * 1 added * 0 removed Changed files: * A core/tests/meson.build
You need to be logged in to leave comments.
Login now