##// END OF EJS Templates
Increase spacing at the bottom of the visu to give more space for dropping in a new zone
trabillard -
r978:839cf5f776e4
parent child
Show More
@@ -1,319 +1,320
1 1 #include "Visualization/VisualizationTabWidget.h"
2 2 #include "Visualization/IVisualizationWidgetVisitor.h"
3 3 #include "ui_VisualizationTabWidget.h"
4 4
5 5 #include "Visualization/VisualizationGraphWidget.h"
6 6 #include "Visualization/VisualizationZoneWidget.h"
7 7
8 8 #include "Visualization/MacScrollBarStyle.h"
9 9
10 10 #include "Variable/VariableController.h"
11 11
12 12 #include "Common/MimeTypesDef.h"
13 13
14 14 #include "DragAndDrop/DragDropHelper.h"
15 15 #include "SqpApplication.h"
16 16
17 17 Q_LOGGING_CATEGORY(LOG_VisualizationTabWidget, "VisualizationTabWidget")
18 18
19 19 namespace {
20 20
21 21 /// Generates a default name for a new zone, according to the number of zones already displayed in
22 22 /// the tab
23 23 QString defaultZoneName(const QLayout &layout)
24 24 {
25 25 auto count = 0;
26 26 for (auto i = 0; i < layout.count(); ++i) {
27 27 if (dynamic_cast<VisualizationZoneWidget *>(layout.itemAt(i)->widget())) {
28 28 count++;
29 29 }
30 30 }
31 31
32 32 return QObject::tr("Zone %1").arg(count + 1);
33 33 }
34 34
35 35 /**
36 36 * Applies a function to all zones of the tab represented by its layout
37 37 * @param layout the layout that contains zones
38 38 * @param fun the function to apply to each zone
39 39 */
40 40 template <typename Fun>
41 41 void processZones(QLayout &layout, Fun fun)
42 42 {
43 43 for (auto i = 0; i < layout.count(); ++i) {
44 44 if (auto item = layout.itemAt(i)) {
45 45 if (auto visualizationZoneWidget
46 46 = dynamic_cast<VisualizationZoneWidget *>(item->widget())) {
47 47 fun(*visualizationZoneWidget);
48 48 }
49 49 }
50 50 }
51 51 }
52 52
53 53 } // namespace
54 54
55 55 struct VisualizationTabWidget::VisualizationTabWidgetPrivate {
56 56 explicit VisualizationTabWidgetPrivate(const QString &name) : m_Name{name} {}
57 57
58 58 QString m_Name;
59 59
60 60 #ifdef Q_OS_MAC
61 61 std::unique_ptr<MacScrollBarStyle> m_MacScrollBarStyle = std::make_unique<MacScrollBarStyle>();
62 62 #endif
63 63
64 64 void dropGraph(int index, VisualizationTabWidget *tabWidget);
65 65 void dropZone(int index, VisualizationTabWidget *tabWidget);
66 66 void dropVariables(const QList<std::shared_ptr<Variable> > &variables, int index,
67 67 VisualizationTabWidget *tabWidget);
68 68 };
69 69
70 70 VisualizationTabWidget::VisualizationTabWidget(const QString &name, QWidget *parent)
71 71 : QWidget{parent},
72 72 ui{new Ui::VisualizationTabWidget},
73 73 impl{spimpl::make_unique_impl<VisualizationTabWidgetPrivate>(name)}
74 74 {
75 75 ui->setupUi(this);
76 76
77 77 #ifdef Q_OS_MAC
78 78 impl->m_MacScrollBarStyle->selfInstallOn(ui->scrollArea, true);
79 79 #endif
80 80
81 81 ui->dragDropContainer->setPlaceHolderType(DragDropHelper::PlaceHolderType::Zone, "Zone");
82 ui->dragDropContainer->layout()->setContentsMargins(0, 0, 0, 5);
82 ui->dragDropContainer->layout()->setContentsMargins(0, 0, 0, 12);
83 ui->dragDropContainer->layout()->setSpacing(0);
83 84 ui->dragDropContainer->setMimeType(MIME_TYPE_GRAPH,
84 85 VisualizationDragDropContainer::DropBehavior::Inserted);
85 86 ui->dragDropContainer->setMimeType(MIME_TYPE_ZONE,
86 87 VisualizationDragDropContainer::DropBehavior::Inserted);
87 88 ui->dragDropContainer->setMimeType(MIME_TYPE_VARIABLE_LIST,
88 89 VisualizationDragDropContainer::DropBehavior::Inserted);
89 90
90 91 ui->dragDropContainer->setAcceptMimeDataFunction([this](auto mimeData) {
91 92 return sqpApp->dragDropHelper().checkMimeDataForVisualization(mimeData,
92 93 ui->dragDropContainer);
93 94 });
94 95
95 96 connect(ui->dragDropContainer, &VisualizationDragDropContainer::dropOccuredInContainer, this,
96 97 &VisualizationTabWidget::dropMimeData);
97 98
98 99 sqpApp->dragDropHelper().addDragDropScrollArea(ui->scrollArea);
99 100
100 101 // Widget is deleted when closed
101 102 setAttribute(Qt::WA_DeleteOnClose);
102 103 }
103 104
104 105 VisualizationTabWidget::~VisualizationTabWidget()
105 106 {
106 107 sqpApp->dragDropHelper().removeDragDropScrollArea(ui->scrollArea);
107 108 delete ui;
108 109 }
109 110
110 111 void VisualizationTabWidget::addZone(VisualizationZoneWidget *zoneWidget)
111 112 {
112 113 ui->dragDropContainer->addDragWidget(zoneWidget);
113 114 }
114 115
115 116 void VisualizationTabWidget::insertZone(int index, VisualizationZoneWidget *zoneWidget)
116 117 {
117 118 ui->dragDropContainer->insertDragWidget(index, zoneWidget);
118 119 }
119 120
120 121 VisualizationZoneWidget *VisualizationTabWidget::createZone(std::shared_ptr<Variable> variable)
121 122 {
122 123 return createZone({variable}, -1);
123 124 }
124 125
125 126 VisualizationZoneWidget *
126 127 VisualizationTabWidget::createZone(const QList<std::shared_ptr<Variable> > &variables, int index)
127 128 {
128 129 auto zoneWidget = createEmptyZone(index);
129 130
130 131 // Creates a new graph into the zone
131 132 zoneWidget->createGraph(variables, index);
132 133
133 134 return zoneWidget;
134 135 }
135 136
136 137 VisualizationZoneWidget *VisualizationTabWidget::createEmptyZone(int index)
137 138 {
138 139 auto zoneWidget
139 140 = new VisualizationZoneWidget{defaultZoneName(*ui->dragDropContainer->layout()), this};
140 141 this->insertZone(index, zoneWidget);
141 142
142 143 return zoneWidget;
143 144 }
144 145
145 146 void VisualizationTabWidget::accept(IVisualizationWidgetVisitor *visitor)
146 147 {
147 148 if (visitor) {
148 149 visitor->visitEnter(this);
149 150
150 151 // Apply visitor to zone children: widgets different from zones are not visited (no action)
151 152 processZones(tabLayout(), [visitor](VisualizationZoneWidget &zoneWidget) {
152 153 zoneWidget.accept(visitor);
153 154 });
154 155
155 156 visitor->visitLeave(this);
156 157 }
157 158 else {
158 159 qCCritical(LOG_VisualizationTabWidget()) << tr("Can't visit widget : the visitor is null");
159 160 }
160 161 }
161 162
162 163 bool VisualizationTabWidget::canDrop(const Variable &variable) const
163 164 {
164 165 // A tab can always accomodate a variable
165 166 Q_UNUSED(variable);
166 167 return true;
167 168 }
168 169
169 170 bool VisualizationTabWidget::contains(const Variable &variable) const
170 171 {
171 172 Q_UNUSED(variable);
172 173 return false;
173 174 }
174 175
175 176 QString VisualizationTabWidget::name() const
176 177 {
177 178 return impl->m_Name;
178 179 }
179 180
180 181 void VisualizationTabWidget::closeEvent(QCloseEvent *event)
181 182 {
182 183 // Closes zones in the tab
183 184 processZones(tabLayout(), [](VisualizationZoneWidget &zoneWidget) { zoneWidget.close(); });
184 185
185 186 QWidget::closeEvent(event);
186 187 }
187 188
188 189 QLayout &VisualizationTabWidget::tabLayout() const noexcept
189 190 {
190 191 return *ui->dragDropContainer->layout();
191 192 }
192 193
193 194 void VisualizationTabWidget::dropMimeData(int index, const QMimeData *mimeData)
194 195 {
195 196 if (mimeData->hasFormat(MIME_TYPE_GRAPH)) {
196 197 impl->dropGraph(index, this);
197 198 }
198 199 else if (mimeData->hasFormat(MIME_TYPE_ZONE)) {
199 200 impl->dropZone(index, this);
200 201 }
201 202 else if (mimeData->hasFormat(MIME_TYPE_VARIABLE_LIST)) {
202 203 auto variables = sqpApp->variableController().variablesForMimeData(
203 204 mimeData->data(MIME_TYPE_VARIABLE_LIST));
204 205 impl->dropVariables(variables, index, this);
205 206 }
206 207 else {
207 208 qCWarning(LOG_VisualizationZoneWidget())
208 209 << tr("VisualizationTabWidget::dropMimeData, unknown MIME data received.");
209 210 }
210 211 }
211 212
212 213 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropGraph(
213 214 int index, VisualizationTabWidget *tabWidget)
214 215 {
215 216 auto &helper = sqpApp->dragDropHelper();
216 217
217 218 auto graphWidget = qobject_cast<VisualizationGraphWidget *>(helper.getCurrentDragWidget());
218 219 if (!graphWidget) {
219 220 qCWarning(LOG_VisualizationZoneWidget())
220 221 << tr("VisualizationTabWidget::dropGraph, drop aborted, the dropped graph is not "
221 222 "found or invalid.");
222 223 Q_ASSERT(false);
223 224 return;
224 225 }
225 226
226 227 auto parentDragDropContainer
227 228 = qobject_cast<VisualizationDragDropContainer *>(graphWidget->parentWidget());
228 229 if (!parentDragDropContainer) {
229 230 qCWarning(LOG_VisualizationZoneWidget())
230 231 << tr("VisualizationTabWidget::dropGraph, drop aborted, the parent container of "
231 232 "the dropped graph is not found.");
232 233 Q_ASSERT(false);
233 234 return;
234 235 }
235 236
236 237 auto nbGraph = parentDragDropContainer->countDragWidget();
237 238
238 239 const auto &variables = graphWidget->variables();
239 240
240 241 if (!variables.isEmpty()) {
241 242 // Abort the requests for the variables (if any)
242 243 // Commented, because it's not sure if it's needed or not
243 244 // for (const auto& var : variables)
244 245 //{
245 246 // sqpApp->variableController().onAbortProgressRequested(var);
246 247 //}
247 248
248 249 if (nbGraph == 1) {
249 250 // This is the only graph in the previous zone, close the zone
250 251 helper.delayedCloseWidget(graphWidget->parentZoneWidget());
251 252 }
252 253 else {
253 254 // Close the graph
254 255 helper.delayedCloseWidget(graphWidget);
255 256 }
256 257
257 258 tabWidget->createZone(variables, index);
258 259 }
259 260 else {
260 261 // The graph is empty, create an empty zone and move the graph inside
261 262
262 263 auto parentZoneWidget = graphWidget->parentZoneWidget();
263 264
264 265 parentDragDropContainer->layout()->removeWidget(graphWidget);
265 266
266 267 auto zoneWidget = tabWidget->createEmptyZone(index);
267 268 zoneWidget->addGraph(graphWidget);
268 269
269 270 // Close the old zone if it was the only graph inside
270 271 if (nbGraph == 1) {
271 272 helper.delayedCloseWidget(parentZoneWidget);
272 273 }
273 274 }
274 275 }
275 276
276 277 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropZone(
277 278 int index, VisualizationTabWidget *tabWidget)
278 279 {
279 280 auto &helper = sqpApp->dragDropHelper();
280 281
281 282 auto zoneWidget = qobject_cast<VisualizationZoneWidget *>(helper.getCurrentDragWidget());
282 283 if (!zoneWidget) {
283 284 qCWarning(LOG_VisualizationZoneWidget())
284 285 << tr("VisualizationTabWidget::dropZone, drop aborted, the dropped zone is not "
285 286 "found or invalid.");
286 287 Q_ASSERT(false);
287 288 return;
288 289 }
289 290
290 291 auto parentDragDropContainer
291 292 = qobject_cast<VisualizationDragDropContainer *>(zoneWidget->parentWidget());
292 293 if (!parentDragDropContainer) {
293 294 qCWarning(LOG_VisualizationZoneWidget())
294 295 << tr("VisualizationTabWidget::dropZone, drop aborted, the parent container of "
295 296 "the dropped zone is not found.");
296 297 Q_ASSERT(false);
297 298 return;
298 299 }
299 300
300 301 // Simple move of the zone, no variable operation associated
301 302 parentDragDropContainer->layout()->removeWidget(zoneWidget);
302 303 tabWidget->ui->dragDropContainer->insertDragWidget(index, zoneWidget);
303 304 }
304 305
305 306 void VisualizationTabWidget::VisualizationTabWidgetPrivate::dropVariables(
306 307 const QList<std::shared_ptr<Variable> > &variables, int index,
307 308 VisualizationTabWidget *tabWidget)
308 309 {
309 310 // Note: the AcceptMimeDataFunction (set on the drop container) ensure there is a single and
310 311 // compatible variable here
311 312 if (variables.count() > 1) {
312 313 qCWarning(LOG_VisualizationZoneWidget())
313 314 << tr("VisualizationTabWidget::dropVariables, dropping multiple variables, operation "
314 315 "aborted.");
315 316 return;
316 317 }
317 318
318 319 tabWidget->createZone(variables, index);
319 320 }
@@ -1,125 +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 <number>0</number>
30 <number>6</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 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 110 </layout>
111 111 </widget>
112 112 </item>
113 113 </layout>
114 114 </widget>
115 115 <customwidgets>
116 116 <customwidget>
117 117 <class>VisualizationDragDropContainer</class>
118 118 <extends>QFrame</extends>
119 119 <header>Visualization/VisualizationDragDropContainer.h</header>
120 120 <container>1</container>
121 121 </customwidget>
122 122 </customwidgets>
123 123 <resources/>
124 124 <connections/>
125 125 </ui>
General Comments 1
Under Review
author

Auto status change to "Under Review"

You need to be logged in to leave comments. Login now