##// END OF EJS Templates
Fix some glitches which occurred when dragging in the visualization something from the sides.
trabillard -
r886:4ed691514436
parent child
Show More
@@ -1,52 +1,52
1 1 #ifndef SCIQLOP_VISUALIZATIONDRAGDROPCONTAINER_H
2 2 #define SCIQLOP_VISUALIZATIONDRAGDROPCONTAINER_H
3 3
4 4 #include <Common/spimpl.h>
5 #include <QFrame>
5 6 #include <QLoggingCategory>
6 7 #include <QMimeData>
7 8 #include <QVBoxLayout>
8 #include <QWidget>
9 9
10 10 #include <functional>
11 11
12 12 Q_DECLARE_LOGGING_CATEGORY(LOG_VisualizationDragDropContainer)
13 13
14 14 class VisualizationDragWidget;
15 15
16 class VisualizationDragDropContainer : public QWidget {
16 class VisualizationDragDropContainer : public QFrame {
17 17 Q_OBJECT
18 18
19 19 signals:
20 20 void dropOccuredInContainer(int dropIndex, const QMimeData *mimeData);
21 21 void dropOccuredOnWidget(VisualizationDragWidget *dragWidget, const QMimeData *mimeData);
22 22
23 23 public:
24 24 enum class DropBehavior { Inserted, Merged, InsertedAndMerged };
25 25 using AcceptMimeDataFunction = std::function<bool(const QMimeData *mimeData)>;
26 26
27 27 VisualizationDragDropContainer(QWidget *parent = nullptr);
28 28
29 29 void addDragWidget(VisualizationDragWidget *dragWidget);
30 30 void insertDragWidget(int index, VisualizationDragWidget *dragWidget);
31 31
32 32 void addAcceptedMimeType(const QString &mimeType, DropBehavior behavior);
33 33
34 34 int countDragWidget() const;
35 35
36 36 void setAcceptMimeDataFunction(AcceptMimeDataFunction fun);
37 37
38 38 protected:
39 39 void dragEnterEvent(QDragEnterEvent *event);
40 40 void dragLeaveEvent(QDragLeaveEvent *event);
41 41 void dragMoveEvent(QDragMoveEvent *event);
42 42 void dropEvent(QDropEvent *event);
43 43
44 44 private:
45 45 class VisualizationDragDropContainerPrivate;
46 46 spimpl::unique_impl_ptr<VisualizationDragDropContainerPrivate> impl;
47 47
48 48 private slots:
49 49 void startDrag(VisualizationDragWidget *dragWidget, const QPoint &dragPosition);
50 50 };
51 51
52 52 #endif // SCIQLOP_VISUALIZATIONDRAGDROPCONTAINER_H
@@ -1,435 +1,442
1 1 #include "Visualization/VisualizationDragDropContainer.h"
2 2 #include "DragDropHelper.h"
3 3 #include "SqpApplication.h"
4 4 #include "Visualization/VisualizationDragWidget.h"
5 5
6 6 #include "Common/VisualizationDef.h"
7 7
8 8 #include <QDrag>
9 9 #include <QDragEnterEvent>
10 10 #include <QVBoxLayout>
11 11
12 12 #include <cmath>
13 13 #include <memory>
14 14
15 15 Q_LOGGING_CATEGORY(LOG_VisualizationDragDropContainer, "VisualizationDragDropContainer")
16 16
17 17 struct VisualizationDragDropContainer::VisualizationDragDropContainerPrivate {
18 18
19 19 QVBoxLayout *m_Layout;
20 20 QHash<QString, VisualizationDragDropContainer::DropBehavior> m_AcceptedMimeTypes;
21 21
22 22 VisualizationDragDropContainer::AcceptMimeDataFunction m_AcceptMimeDataFun
23 23 = [](auto mimeData) { return true; };
24 24
25 25 int m_MinContainerHeight = 0;
26 26
27 27 explicit VisualizationDragDropContainerPrivate(QWidget *widget)
28 28 {
29 29 m_Layout = new QVBoxLayout(widget);
30 30 m_Layout->setContentsMargins(0, 0, 0, 0);
31 31 }
32 32
33 33 bool acceptMimeData(const QMimeData *data) const
34 34 {
35 35 for (const auto &type : m_AcceptedMimeTypes.keys()) {
36 36 if (data->hasFormat(type) && m_AcceptMimeDataFun(data)) {
37 37 return true;
38 38 }
39 39 }
40 40
41 41 return false;
42 42 }
43 43
44 44 bool allowMergeForMimeData(const QMimeData *data) const
45 45 {
46 46 bool result = false;
47 47 for (auto it = m_AcceptedMimeTypes.constBegin(); it != m_AcceptedMimeTypes.constEnd();
48 48 ++it) {
49 49
50 50 if (data->hasFormat(it.key())
51 51 && (it.value() == VisualizationDragDropContainer::DropBehavior::Merged
52 52 || it.value()
53 53 == VisualizationDragDropContainer::DropBehavior::InsertedAndMerged)) {
54 54 result = true;
55 55 }
56 56 else if (data->hasFormat(it.key())
57 57 && it.value() == VisualizationDragDropContainer::DropBehavior::Inserted) {
58 58 // Merge is forbidden if the mime data contain an acceptable type which cannot be
59 59 // merged
60 60 result = false;
61 61 break;
62 62 }
63 63 }
64 64
65 65 return result;
66 66 }
67 67
68 68 bool allowInsertForMimeData(const QMimeData *data) const
69 69 {
70 70 for (auto it = m_AcceptedMimeTypes.constBegin(); it != m_AcceptedMimeTypes.constEnd();
71 71 ++it) {
72 72 if (data->hasFormat(it.key())
73 73 && (it.value() == VisualizationDragDropContainer::DropBehavior::Inserted
74 74 || it.value()
75 75 == VisualizationDragDropContainer::DropBehavior::InsertedAndMerged)) {
76 76 return true;
77 77 }
78 78 }
79 79
80 80 return false;
81 81 }
82 82
83 83 bool hasPlaceHolder() const
84 84 {
85 85 return sqpApp->dragDropHelper().placeHolder().parentWidget() == m_Layout->parentWidget();
86 86 }
87 87
88 88 VisualizationDragWidget *getChildDragWidgetAt(const QWidget *parent, const QPoint &pos) const
89 89 {
90 90 VisualizationDragWidget *dragWidget = nullptr;
91 91
92 92 for (auto child : parent->children()) {
93 93 auto widget = qobject_cast<VisualizationDragWidget *>(child);
94 94 if (widget && widget->isVisible()) {
95 95 if (widget->frameGeometry().contains(pos)) {
96 96 dragWidget = widget;
97 97 break;
98 98 }
99 99 }
100 100 }
101 101
102 102 return dragWidget;
103 103 }
104 104
105 105 bool cursorIsInContainer(QWidget *container) const
106 106 {
107 107 return container->isAncestorOf(sqpApp->widgetAt(QCursor::pos()));
108 108 }
109 109
110 int countDragWidget(const QWidget *parent) const
110 int countDragWidget(const QWidget *parent, bool onlyVisible = false) const
111 111 {
112 112 auto nbGraph = 0;
113 113 for (auto child : parent->children()) {
114 114 if (qobject_cast<VisualizationDragWidget *>(child)) {
115 nbGraph += 1;
115 if (!onlyVisible || qobject_cast<VisualizationDragWidget *>(child)->isVisible()) {
116 nbGraph += 1;
117 }
116 118 }
117 119 }
118 120
119 121 return nbGraph;
120 122 }
121 123
122 124 void findPlaceHolderPosition(const QPoint &pos, bool canInsert, bool canMerge,
123 125 const VisualizationDragDropContainer *container);
124 126 };
125 127
126 128 VisualizationDragDropContainer::VisualizationDragDropContainer(QWidget *parent)
127 : QWidget{parent},
129 : QFrame{parent},
128 130 impl{spimpl::make_unique_impl<VisualizationDragDropContainerPrivate>(this)}
129 131 {
130 132 setAcceptDrops(true);
131 133 }
132 134
133 135 void VisualizationDragDropContainer::addDragWidget(VisualizationDragWidget *dragWidget)
134 136 {
135 137 impl->m_Layout->addWidget(dragWidget);
136 138 disconnect(dragWidget, &VisualizationDragWidget::dragDetected, nullptr, nullptr);
137 139 connect(dragWidget, &VisualizationDragWidget::dragDetected, this,
138 140 &VisualizationDragDropContainer::startDrag);
139 141 }
140 142
141 143 void VisualizationDragDropContainer::insertDragWidget(int index,
142 144 VisualizationDragWidget *dragWidget)
143 145 {
144 146 impl->m_Layout->insertWidget(index, dragWidget);
145 147 disconnect(dragWidget, &VisualizationDragWidget::dragDetected, nullptr, nullptr);
146 148 connect(dragWidget, &VisualizationDragWidget::dragDetected, this,
147 149 &VisualizationDragDropContainer::startDrag);
148 150 }
149 151
150 152 void VisualizationDragDropContainer::addAcceptedMimeType(
151 153 const QString &mimeType, VisualizationDragDropContainer::DropBehavior behavior)
152 154 {
153 155 impl->m_AcceptedMimeTypes[mimeType] = behavior;
154 156 }
155 157
156 158 int VisualizationDragDropContainer::countDragWidget() const
157 159 {
158 160 return impl->countDragWidget(this);
159 161 }
160 162
161 163 void VisualizationDragDropContainer::setAcceptMimeDataFunction(
162 164 VisualizationDragDropContainer::AcceptMimeDataFunction fun)
163 165 {
164 166 impl->m_AcceptMimeDataFun = fun;
165 167 }
166 168
167 169 void VisualizationDragDropContainer::startDrag(VisualizationDragWidget *dragWidget,
168 170 const QPoint &dragPosition)
169 171 {
170 172 auto &helper = sqpApp->dragDropHelper();
171 173 helper.resetDragAndDrop();
172 174
173 175 // Note: The management of the drag object is done by Qt
174 176 auto drag = new QDrag{dragWidget};
175 177 drag->setHotSpot(dragPosition);
176 178
177 179 auto mimeData = dragWidget->mimeData();
178 180 drag->setMimeData(mimeData);
179 181
180 182 auto pixmap = QPixmap(dragWidget->size());
181 183 dragWidget->render(&pixmap);
182 184 drag->setPixmap(pixmap);
183 185
184 186 auto image = pixmap.toImage();
185 187 mimeData->setImageData(image);
186 188 mimeData->setUrls({helper.imageTemporaryUrl(image)});
187 189
188 190 if (impl->m_Layout->indexOf(dragWidget) >= 0) {
189 191 helper.setCurrentDragWidget(dragWidget);
190 192
191 193 if (impl->cursorIsInContainer(this)) {
192 194 auto dragWidgetIndex = impl->m_Layout->indexOf(dragWidget);
193 195 helper.insertPlaceHolder(impl->m_Layout, dragWidgetIndex);
194 196 dragWidget->setVisible(false);
195 197 }
196 198 else {
197 199 // The drag starts directly outside the drop zone
198 200 // do not add the placeHolder
199 201 }
200 202
201 203 // Note: The exec() is blocking on windows but not on linux and macOS
202 204 drag->exec(Qt::MoveAction | Qt::CopyAction);
203 205 }
204 206 else {
205 207 qCWarning(LOG_VisualizationDragDropContainer())
206 208 << tr("VisualizationDragDropContainer::startDrag, drag aborted, the specified "
207 209 "VisualizationDragWidget is not found in this container.");
208 210 }
209 211 }
210 212
211 213 void VisualizationDragDropContainer::dragEnterEvent(QDragEnterEvent *event)
212 214 {
213 215 if (impl->acceptMimeData(event->mimeData())) {
214 216 event->acceptProposedAction();
215 217
216 218 auto &helper = sqpApp->dragDropHelper();
217 219
218 220 if (!impl->hasPlaceHolder()) {
219 221 auto dragWidget = helper.getCurrentDragWidget();
220 222
221 223 if (dragWidget) {
222 224 // If the drag&drop is internal to the visualization, entering the container hide
223 225 // the dragWidget which was made visible by the dragLeaveEvent
224 226 auto parentWidget
225 227 = qobject_cast<VisualizationDragDropContainer *>(dragWidget->parentWidget());
226 228 if (parentWidget) {
227 229 dragWidget->setVisible(false);
228 230 }
229 231 }
230 232
231 233 auto canMerge = impl->allowMergeForMimeData(event->mimeData());
232 234 auto canInsert = impl->allowInsertForMimeData(event->mimeData());
233 235 impl->findPlaceHolderPosition(event->pos(), canInsert, canMerge, this);
234 236 }
235 237 else {
236 238 // do nothing
237 239 }
238 240 }
239 241 else {
240 242 event->ignore();
241 243 }
242 244
243 245 QWidget::dragEnterEvent(event);
244 246 }
245 247
246 248 void VisualizationDragDropContainer::dragLeaveEvent(QDragLeaveEvent *event)
247 249 {
248 250 Q_UNUSED(event);
249 251
250 252 auto &helper = sqpApp->dragDropHelper();
251 253
252 254 if (!impl->cursorIsInContainer(this)) {
253 255 helper.removePlaceHolder();
254 256 helper.setHightlightedDragWidget(nullptr);
255 257 impl->m_MinContainerHeight = 0;
256 258
257 259 auto dragWidget = helper.getCurrentDragWidget();
258 260 if (dragWidget) {
259 261 // dragWidget has a value only if the drag is started from the visualization
260 262 // In that case, shows the drag widget at its original place
261 263 // So the drag widget doesn't stay hidden if the drop occurs outside the visualization
262 264 // drop zone (It is not possible to catch a drop event outside of the application)
263 265
264 266 if (dragWidget) {
265 267 dragWidget->setVisible(true);
266 268 }
267 269 }
268 270 }
269 271 else {
270 272 // Leave event probably received for a child widget.
271 273 // Do nothing.
272 274 // Note: The DragLeave event, doesn't have any mean to determine who sent it.
273 275 }
274 276
275 277 QWidget::dragLeaveEvent(event);
276 278 }
277 279
278 280 void VisualizationDragDropContainer::dragMoveEvent(QDragMoveEvent *event)
279 281 {
280 282 if (impl->acceptMimeData(event->mimeData())) {
281 283 auto canMerge = impl->allowMergeForMimeData(event->mimeData());
282 284 auto canInsert = impl->allowInsertForMimeData(event->mimeData());
283 285 impl->findPlaceHolderPosition(event->pos(), canInsert, canMerge, this);
284 286 }
285 287 else {
286 288 event->ignore();
287 289 }
288 290
289 291 QWidget::dragMoveEvent(event);
290 292 }
291 293
292 294 void VisualizationDragDropContainer::dropEvent(QDropEvent *event)
293 295 {
294 296 auto &helper = sqpApp->dragDropHelper();
295 297
296 298 if (impl->acceptMimeData(event->mimeData())) {
297 299 auto dragWidget = helper.getCurrentDragWidget();
298 300 if (impl->hasPlaceHolder()) {
299 301 // drop where the placeHolder is located
300 302
301 303 auto canInsert = impl->allowInsertForMimeData(event->mimeData());
302 304 if (canInsert) {
303 305 auto droppedIndex = impl->m_Layout->indexOf(&helper.placeHolder());
304 306
305 307 if (dragWidget) {
306 308 auto dragWidgetIndex = impl->m_Layout->indexOf(dragWidget);
307 309 if (dragWidgetIndex >= 0 && dragWidgetIndex < droppedIndex) {
308 310 // Correction of the index if the drop occurs in the same container
309 311 // and if the drag is started from the visualization (in that case, the
310 312 // dragWidget is hidden)
311 313 droppedIndex -= 1;
312 314 }
313 315
314 316 dragWidget->setVisible(true);
315 317 }
316 318
317 319 event->acceptProposedAction();
318 320
319 321 helper.removePlaceHolder();
320 322
321 323 emit dropOccuredInContainer(droppedIndex, event->mimeData());
322 324 }
323 325 else {
324 326 qCWarning(LOG_VisualizationDragDropContainer()) << tr(
325 327 "VisualizationDragDropContainer::dropEvent, dropping on the placeHolder, but "
326 328 "the insertion is forbidden.");
327 329 Q_ASSERT(false);
328 330 }
329 331 }
330 332 else if (helper.getHightlightedDragWidget()) {
331 333 // drop on the highlighted widget
332 334
333 335 auto canMerge = impl->allowMergeForMimeData(event->mimeData());
334 336 if (canMerge) {
335 337 event->acceptProposedAction();
336 338 emit dropOccuredOnWidget(helper.getHightlightedDragWidget(), event->mimeData());
337 339 }
338 340 else {
339 341 qCWarning(LOG_VisualizationDragDropContainer())
340 342 << tr("VisualizationDragDropContainer::dropEvent, dropping on a widget, but "
341 343 "the merge is forbidden.");
342 344 Q_ASSERT(false);
343 345 }
344 346 }
345 347 }
346 348 else {
347 349 event->ignore();
348 350 }
349 351
350 352 sqpApp->dragDropHelper().setHightlightedDragWidget(nullptr);
351 353 impl->m_MinContainerHeight = 0;
352 354
353 355 QWidget::dropEvent(event);
354 356 }
355 357
356 358
357 359 void VisualizationDragDropContainer::VisualizationDragDropContainerPrivate::findPlaceHolderPosition(
358 360 const QPoint &pos, bool canInsert, bool canMerge,
359 361 const VisualizationDragDropContainer *container)
360 362 {
361 363 auto &helper = sqpApp->dragDropHelper();
362 364
363 auto dragWidgetHovered = getChildDragWidgetAt(container, pos);
364 if (dragWidgetHovered) {
365 auto absPos = container->mapToGlobal(pos);
366 auto isOnPlaceHolder = sqpApp->widgetAt(absPos) == &(helper.placeHolder());
367
368 if (countDragWidget(container, true) == 0) {
369 // Drop on an empty container, just add the placeHolder at the top
370 helper.insertPlaceHolder(m_Layout, 0);
371 }
372 else if (!isOnPlaceHolder) {
365 373 auto nbDragWidget = countDragWidget(container);
366 374 if (nbDragWidget > 0) {
367 375
368 376 if (m_MinContainerHeight == 0) {
369 377 m_MinContainerHeight = container->size().height();
370 378 }
371 379
372 380 m_MinContainerHeight = qMin(m_MinContainerHeight, container->size().height());
373 381 auto graphHeight = qMax(m_MinContainerHeight / nbDragWidget, GRAPH_MINIMUM_HEIGHT);
374 382
375 383 auto posY = pos.y();
376 384 auto dropIndex = floor(posY / graphHeight);
377 385 auto zoneSize = qMin(graphHeight / 4.0, 75.0);
378 386
379 387
380 388 auto isOnTop = posY < dropIndex * graphHeight + zoneSize;
381 389 auto isOnBottom = posY > (dropIndex + 1) * graphHeight - zoneSize;
382 390
383 391 auto placeHolderIndex = m_Layout->indexOf(&(helper.placeHolder()));
384 392
393 auto dragWidgetHovered = getChildDragWidgetAt(container, pos);
394
385 395 if (canInsert && (isOnTop || isOnBottom || !canMerge)) {
386 396 if (isOnBottom) {
387 397 dropIndex += 1;
388 398 }
389 399
390 400 if (helper.getCurrentDragWidget()) {
391 401 auto dragWidgetIndex = m_Layout->indexOf(helper.getCurrentDragWidget());
392 402 if (dragWidgetIndex >= 0 && dragWidgetIndex <= dropIndex) {
393 403 // Correction of the index if the drop occurs in the same container
394 404 // and if the drag is started from the visualization (in that case, the
395 405 // dragWidget is hidden)
396 406 dropIndex += 1;
397 407 }
398 408 }
399 409
400 410 if (dropIndex != placeHolderIndex) {
401 411 helper.insertPlaceHolder(m_Layout, dropIndex);
402 412 }
403 413
404 414 helper.setHightlightedDragWidget(nullptr);
405 415 }
406 else if (canMerge) {
416 else if (canMerge && dragWidgetHovered) {
407 417 // drop on the middle -> merge
408 418 if (hasPlaceHolder()) {
409 419 helper.removePlaceHolder();
410 420 }
411 421
412 422 helper.setHightlightedDragWidget(dragWidgetHovered);
413 423 }
414 424 else {
415 qCWarning(LOG_VisualizationDragDropContainer())
416 << tr("VisualizationDragDropContainer::findPlaceHolderPosition, no valid drop "
417 "action.");
425 qCWarning(LOG_VisualizationDragDropContainer()) << tr(
426 "VisualizationDragDropContainer::findPlaceHolderPosition, no valid drop "
427 "action.");
418 428 Q_ASSERT(false);
419 429 }
420 430 }
421 431 else {
422 qCWarning(LOG_VisualizationDragDropContainer()) << tr(
423 "VisualizationDragDropContainer::findPlaceHolderPosition, no widget found in the "
424 "container");
432 qCWarning(LOG_VisualizationDragDropContainer())
433 << tr("VisualizationDragDropContainer::findPlaceHolderPosition, no widget "
434 "found in the "
435 "container");
425 436 }
426 437 }
427 else if (!hasPlaceHolder() && canInsert) {
428 // Drop on an empty container, just add the placeHolder at the top
429 helper.insertPlaceHolder(m_Layout, 0);
430 }
431 438 else {
432 // No hovered drag widget, the mouse is probably hover the placeHolder
439 // the mouse is hover the placeHolder
433 440 // Do nothing
434 441 }
435 442 }
@@ -1,84 +1,88
1 1 <?xml version="1.0" encoding="UTF-8"?>
2 2 <ui version="4.0">
3 3 <class>VisualizationTabWidget</class>
4 4 <widget class="QWidget" name="VisualizationTabWidget">
5 5 <property name="geometry">
6 6 <rect>
7 7 <x>0</x>
8 8 <y>0</y>
9 9 <width>400</width>
10 10 <height>300</height>
11 11 </rect>
12 12 </property>
13 13 <property name="windowTitle">
14 14 <string>Form</string>
15 15 </property>
16 16 <layout class="QVBoxLayout" name="verticalLayout">
17 17 <property name="leftMargin">
18 18 <number>0</number>
19 19 </property>
20 20 <property name="topMargin">
21 21 <number>0</number>
22 22 </property>
23 23 <property name="rightMargin">
24 24 <number>0</number>
25 25 </property>
26 26 <property name="bottomMargin">
27 27 <number>0</number>
28 28 </property>
29 29 <item>
30 30 <widget class="QScrollArea" name="scrollArea">
31 31 <property name="frameShape">
32 32 <enum>QFrame::NoFrame</enum>
33 33 </property>
34 34 <property name="frameShadow">
35 35 <enum>QFrame::Sunken</enum>
36 36 </property>
37 37 <property name="widgetResizable">
38 38 <bool>true</bool>
39 39 </property>
40 40 <widget class="QWidget" name="scrollAreaWidgetContents">
41 41 <property name="geometry">
42 42 <rect>
43 43 <x>0</x>
44 44 <y>0</y>
45 45 <width>400</width>
46 46 <height>300</height>
47 47 </rect>
48 48 </property>
49 49 <layout class="QVBoxLayout" name="verticalLayout_3">
50 50 <property name="spacing">
51 51 <number>3</number>
52 52 </property>
53 53 <property name="leftMargin">
54 54 <number>0</number>
55 55 </property>
56 56 <property name="topMargin">
57 57 <number>0</number>
58 58 </property>
59 59 <property name="rightMargin">
60 60 <number>0</number>
61 61 </property>
62 62 <property name="bottomMargin">
63 63 <number>0</number>
64 64 </property>
65 65 <item>
66 <widget class="VisualizationDragDropContainer" name="dragDropContainer" native="true"/>
66 <widget class="VisualizationDragDropContainer" name="dragDropContainer">
67 <property name="lineWidth">
68 <number>0</number>
69 </property>
70 </widget>
67 71 </item>
68 72 </layout>
69 73 </widget>
70 74 </widget>
71 75 </item>
72 76 </layout>
73 77 </widget>
74 78 <customwidgets>
75 79 <customwidget>
76 80 <class>VisualizationDragDropContainer</class>
77 <extends>QWidget</extends>
81 <extends>QFrame</extends>
78 82 <header>Visualization/VisualizationDragDropContainer.h</header>
79 83 <container>1</container>
80 84 </customwidget>
81 85 </customwidgets>
82 86 <resources/>
83 87 <connections/>
84 88 </ui>
@@ -1,128 +1,125
1 1 <?xml version="1.0" encoding="UTF-8"?>
2 2 <ui version="4.0">
3 3 <class>VisualizationZoneWidget</class>
4 4 <widget class="QWidget" name="VisualizationZoneWidget">
5 5 <property name="geometry">
6 6 <rect>
7 7 <x>0</x>
8 8 <y>0</y>
9 9 <width>400</width>
10 10 <height>300</height>
11 11 </rect>
12 12 </property>
13 13 <property name="windowTitle">
14 14 <string>Form</string>
15 15 </property>
16 16 <layout class="QVBoxLayout" name="verticalLayout_2">
17 17 <property name="spacing">
18 18 <number>0</number>
19 19 </property>
20 20 <property name="leftMargin">
21 21 <number>0</number>
22 22 </property>
23 23 <property name="topMargin">
24 24 <number>0</number>
25 25 </property>
26 26 <property name="rightMargin">
27 27 <number>0</number>
28 28 </property>
29 29 <property name="bottomMargin">
30 30 <number>0</number>
31 31 </property>
32 32 <item>
33 33 <widget class="QWidget" name="infobar" native="true">
34 34 <property name="sizePolicy">
35 35 <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
36 36 <horstretch>0</horstretch>
37 37 <verstretch>0</verstretch>
38 38 </sizepolicy>
39 39 </property>
40 40 <layout class="QHBoxLayout" name="horizontalLayout">
41 41 <property name="spacing">
42 42 <number>0</number>
43 43 </property>
44 44 <property name="leftMargin">
45 45 <number>0</number>
46 46 </property>
47 47 <property name="topMargin">
48 48 <number>0</number>
49 49 </property>
50 50 <property name="rightMargin">
51 51 <number>0</number>
52 52 </property>
53 53 <property name="bottomMargin">
54 54 <number>0</number>
55 55 </property>
56 56 <item>
57 57 <widget class="QLabel" name="zoneNameLabel">
58 58 <property name="styleSheet">
59 59 <string notr="true">color: rgb(127, 127, 127);
60 60 </string>
61 61 </property>
62 62 <property name="text">
63 63 <string>TextLabel</string>
64 64 </property>
65 65 </widget>
66 66 </item>
67 67 <item>
68 68 <widget class="QToolButton" name="closeButton">
69 69 <property name="styleSheet">
70 70 <string notr="true">background-color: transparent;</string>
71 71 </property>
72 72 <property name="text">
73 73 <string>Close</string>
74 74 </property>
75 75 </widget>
76 76 </item>
77 77 </layout>
78 78 </widget>
79 79 </item>
80 80 <item>
81 <widget class="QFrame" name="visualizationZoneFrame">
81 <widget class="VisualizationDragDropContainer" name="dragDropContainer">
82 82 <property name="sizePolicy">
83 83 <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
84 84 <horstretch>0</horstretch>
85 85 <verstretch>0</verstretch>
86 86 </sizepolicy>
87 87 </property>
88 88 <property name="frameShape">
89 89 <enum>QFrame::Box</enum>
90 90 </property>
91 91 <property name="frameShadow">
92 92 <enum>QFrame::Raised</enum>
93 93 </property>
94 94 <property name="lineWidth">
95 95 <number>1</number>
96 96 </property>
97 97 <layout class="QVBoxLayout" name="verticalLayout">
98 98 <property name="leftMargin">
99 99 <number>0</number>
100 100 </property>
101 101 <property name="topMargin">
102 102 <number>0</number>
103 103 </property>
104 104 <property name="rightMargin">
105 105 <number>0</number>
106 106 </property>
107 107 <property name="bottomMargin">
108 108 <number>0</number>
109 109 </property>
110 <item>
111 <widget class="VisualizationDragDropContainer" name="dragDropContainer" native="true"/>
112 </item>
113 110 </layout>
114 111 </widget>
115 112 </item>
116 113 </layout>
117 114 </widget>
118 115 <customwidgets>
119 116 <customwidget>
120 117 <class>VisualizationDragDropContainer</class>
121 <extends>QWidget</extends>
118 <extends>QFrame</extends>
122 119 <header>Visualization/VisualizationDragDropContainer.h</header>
123 120 <container>1</container>
124 121 </customwidget>
125 122 </customwidgets>
126 123 <resources/>
127 124 <connections/>
128 125 </ui>
General Comments 3
Under Review
author

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