1 | |
2 | // Copyright (C) 2023 The Qt Company Ltd. |
3 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only |
4 | |
5 | #include <QtGraphsWidgets/q3dgraphswidgetitem.h> |
6 | #include <private/q3dgraphswidgetitem_p.h> |
7 | #include <private/q3dscene_p.h> |
8 | #include <private/qquickgraphsitem_p.h> |
9 | |
10 | #ifdef Q_OS_DARWIN |
11 | #include <QtQuick3D/qquick3d.h> |
12 | #endif |
13 | |
14 | QT_BEGIN_NAMESPACE |
15 | |
16 | /*! |
17 | * \class Q3DGraphsWidgetItem |
18 | * \inmodule QtGraphsWidgets |
19 | * \ingroup graphs_3D_widgets |
20 | * \brief The Q3DGraphsWidgetItem class provides a window and render loop for |
21 | * graphs. |
22 | * |
23 | * This class subclasses a QWindow and provides render loop for graphs |
24 | * inheriting it. |
25 | * |
26 | * You should not need to use this class directly, but one of its subclasses |
27 | * instead. |
28 | * |
29 | * Multisampling is turned off by default in \c {QSurfaceFormat}. |
30 | * To enable multisampling, set a custom surface format as |
31 | * a default surface format. To get the custom surface format, |
32 | * use \l {QQuick3D::idealSurfaceFormat()}. |
33 | * |
34 | * \sa Q3DBarsWidgetItem, Q3DScatterWidgetItem, Q3DSurfaceWidgetItem, {Qt Graphs C++ Classes for 3D} |
35 | */ |
36 | |
37 | /*! |
38 | * \internal |
39 | */ |
40 | Q3DGraphsWidgetItem::Q3DGraphsWidgetItem(Q3DGraphsWidgetItemPrivate &dd, |
41 | QObject *parent, |
42 | const QString &graphType) |
43 | : QObject(dd, parent) |
44 | { |
45 | Q_D(Q3DGraphsWidgetItem); |
46 | d->m_graphType = graphType; |
47 | } |
48 | |
49 | /*! |
50 | * Destroys Q3DGraphsWidgetItem. |
51 | */ |
52 | Q3DGraphsWidgetItem::~Q3DGraphsWidgetItem() |
53 | { |
54 | } |
55 | |
56 | /*! |
57 | * Adds the given \a theme to the graph. The themes added via addTheme are not |
58 | * taken in to use directly. Only the ownership of the theme is given to the |
59 | * graph. The \a theme must not be null or already added to another graph. |
60 | * |
61 | * \sa releaseTheme(), setActiveTheme() |
62 | */ |
63 | void Q3DGraphsWidgetItem::addTheme(QGraphsTheme *theme) |
64 | { |
65 | Q_D(Q3DGraphsWidgetItem); |
66 | d->m_graphsItem->addTheme(theme); |
67 | } |
68 | |
69 | /*! |
70 | * Releases the ownership of the \a theme back to the caller, if it was added to |
71 | * this graph. If the released \a theme is in use, a new default theme will be |
72 | * created and set active. |
73 | * |
74 | * If the default theme is released and added back later, it behaves as any |
75 | * other theme would. |
76 | * |
77 | * \sa addTheme(), setActiveTheme() |
78 | */ |
79 | void Q3DGraphsWidgetItem::releaseTheme(QGraphsTheme *theme) |
80 | { |
81 | Q_D(Q3DGraphsWidgetItem); |
82 | d->m_graphsItem->releaseTheme(theme); |
83 | } |
84 | |
85 | /*! |
86 | * \property Q3DGraphsWidgetItem::activeTheme |
87 | * |
88 | * \brief The active theme of the graph. |
89 | * |
90 | * Sets \a activeTheme as the active theme to be used for the graph. Implicitly |
91 | * calls addTheme() to transfer the ownership of the theme to this graph. |
92 | * |
93 | * If \a activeTheme is null, a temporary default theme is created. This |
94 | * temporary theme is destroyed if any theme is explicitly set later. Properties |
95 | * of the theme can be modified even after setting it, and the modifications |
96 | * take effect immediately. |
97 | */ |
98 | QGraphsTheme *Q3DGraphsWidgetItem::activeTheme() const |
99 | { |
100 | Q_D(const Q3DGraphsWidgetItem); |
101 | return d->m_graphsItem->theme(); |
102 | } |
103 | |
104 | void Q3DGraphsWidgetItem::setActiveTheme(QGraphsTheme *activeTheme) |
105 | { |
106 | Q_D(Q3DGraphsWidgetItem); |
107 | d->m_graphsItem->setTheme(activeTheme); |
108 | } |
109 | |
110 | /*! |
111 | * Returns the list of all added themes. |
112 | * |
113 | * \sa addTheme() |
114 | */ |
115 | QList<QGraphsTheme *> Q3DGraphsWidgetItem::themes() const |
116 | { |
117 | Q_D(const Q3DGraphsWidgetItem); |
118 | return d->m_graphsItem->themes(); |
119 | } |
120 | |
121 | /*! |
122 | * \property Q3DGraphsWidgetItem::selectionMode |
123 | * |
124 | * \brief Item selection mode. |
125 | * |
126 | * A combination of SelectionFlags. By default, \c Item. |
127 | * Different graph types support different selection modes. |
128 | * |
129 | * \sa QtGraphs3D::SelectionFlags |
130 | */ |
131 | QtGraphs3D::SelectionFlags Q3DGraphsWidgetItem::selectionMode() const |
132 | { |
133 | Q_D(const Q3DGraphsWidgetItem); |
134 | return d->m_graphsItem->selectionMode(); |
135 | } |
136 | |
137 | void Q3DGraphsWidgetItem::setSelectionMode(const QtGraphs3D::SelectionFlags &selectionMode) |
138 | { |
139 | Q_D(Q3DGraphsWidgetItem); |
140 | d->m_graphsItem->setSelectionMode(selectionMode); |
141 | } |
142 | |
143 | /*! |
144 | * \property Q3DGraphsWidgetItem::shadowQuality |
145 | * |
146 | * \brief The quality of the shadow. |
147 | * |
148 | * One of the ShadowQuality enum values. By default, \c Medium. |
149 | * |
150 | * \note If setting the shadow quality to a certain level fails, the level is |
151 | * lowered until it is successfully set. The \c shadowQualityChanged signal is |
152 | * emitted each time a change is made. |
153 | * |
154 | * \sa QtGraphs3D::ShadowQuality |
155 | */ |
156 | QtGraphs3D::ShadowQuality Q3DGraphsWidgetItem::shadowQuality() const |
157 | { |
158 | Q_D(const Q3DGraphsWidgetItem); |
159 | return d->m_graphsItem->shadowQuality(); |
160 | } |
161 | |
162 | void Q3DGraphsWidgetItem::setShadowQuality(const QtGraphs3D::ShadowQuality &shadowQuality) |
163 | { |
164 | Q_D(Q3DGraphsWidgetItem); |
165 | d->m_graphsItem->setShadowQuality(shadowQuality); |
166 | } |
167 | |
168 | /*! |
169 | * \property Q3DGraphsWidgetItem::scene |
170 | * \readonly |
171 | * |
172 | * \brief The Q3DScene pointer that can be used to manipulate the scene and |
173 | * access the scene elements. |
174 | * |
175 | * This property is read-only. |
176 | */ |
177 | Q3DScene *Q3DGraphsWidgetItem::scene() const |
178 | { |
179 | Q_D(const Q3DGraphsWidgetItem); |
180 | return (Q3DScene *) d->m_graphsItem->scene(); |
181 | } |
182 | |
183 | /*! |
184 | * Clears selection from all attached series. |
185 | */ |
186 | void Q3DGraphsWidgetItem::clearSelection() |
187 | { |
188 | Q_D(Q3DGraphsWidgetItem); |
189 | d->m_graphsItem->clearSelection(); |
190 | } |
191 | |
192 | /*! |
193 | * Returns whether the \a series has already been added to the graph. |
194 | */ |
195 | bool Q3DGraphsWidgetItem::hasSeries(QAbstract3DSeries *series) const |
196 | { |
197 | Q_D(const Q3DGraphsWidgetItem); |
198 | return d->m_graphsItem->hasSeries(series); |
199 | } |
200 | |
201 | /*! |
202 | * Adds a QCustom3DItem \a item to the graph. Graph takes ownership of the added |
203 | * item. |
204 | * |
205 | * Returns the index to the added item if the add operation was successful, -1 |
206 | * if trying to add a null item, and the index of the item if trying to add an |
207 | * already added item. |
208 | * |
209 | * Items are rendered in the order they have been inserted. The rendering order |
210 | * needs to be taken into account when having solid and transparent items. |
211 | * |
212 | * \sa removeCustomItems(), removeCustomItem(), removeCustomItemAt(), |
213 | * customItems() |
214 | */ |
215 | qsizetype Q3DGraphsWidgetItem::addCustomItem(QCustom3DItem *item) |
216 | { |
217 | Q_D(Q3DGraphsWidgetItem); |
218 | return d->m_graphsItem->addCustomItem(item); |
219 | } |
220 | |
221 | /*! |
222 | * Removes all custom items. Deletes the resources allocated to them. |
223 | */ |
224 | void Q3DGraphsWidgetItem::removeCustomItems() |
225 | { |
226 | Q_D(Q3DGraphsWidgetItem); |
227 | d->m_graphsItem->removeCustomItems(); |
228 | } |
229 | |
230 | /*! |
231 | * Removes the custom \a {item}. Deletes the resources allocated to it. |
232 | */ |
233 | void Q3DGraphsWidgetItem::removeCustomItem(QCustom3DItem *item) |
234 | { |
235 | Q_D(Q3DGraphsWidgetItem); |
236 | d->m_graphsItem->removeCustomItem(item); |
237 | } |
238 | |
239 | /*! |
240 | * Removes all custom items at \a {position}. Deletes the resources allocated to |
241 | * them. |
242 | */ |
243 | void Q3DGraphsWidgetItem::removeCustomItemAt(QVector3D position) |
244 | { |
245 | Q_D(Q3DGraphsWidgetItem); |
246 | d->m_graphsItem->removeCustomItemAt(position); |
247 | } |
248 | |
249 | /*! |
250 | * Gets ownership of given \a item back and removes the \a item from the graph. |
251 | * |
252 | * \note If the same item is added back to the graph, the texture or the texture |
253 | * file needs to be re-set. |
254 | * |
255 | * \sa QCustom3DItem::setTextureImage(), QCustom3DItem::setTextureFile() |
256 | */ |
257 | void Q3DGraphsWidgetItem::releaseCustomItem(QCustom3DItem *item) |
258 | { |
259 | Q_D(Q3DGraphsWidgetItem); |
260 | return d->m_graphsItem->releaseCustomItem(item); |
261 | } |
262 | |
263 | /*! |
264 | * Returns the list of all added custom items. |
265 | * \sa addCustomItem() |
266 | */ |
267 | QList<QCustom3DItem *> Q3DGraphsWidgetItem::customItems() const |
268 | { |
269 | Q_D(const Q3DGraphsWidgetItem); |
270 | return d->m_graphsItem->customItems(); |
271 | } |
272 | |
273 | /*! |
274 | * Can be used to query the index of the selected label after receiving \c |
275 | * selectedElementChanged signal with any label type. Selection is valid until |
276 | * the next \c selectedElementChanged signal. |
277 | * |
278 | * Returns the index of the selected label, or -1. |
279 | * |
280 | * \sa selectedElement |
281 | */ |
282 | int Q3DGraphsWidgetItem::selectedLabelIndex() const |
283 | { |
284 | Q_D(const Q3DGraphsWidgetItem); |
285 | return d->m_graphsItem->selectedLabelIndex(); |
286 | } |
287 | |
288 | /*! |
289 | * Can be used to get the selected axis after receiving \c |
290 | * selectedElementChanged signal with any label type. Selection is valid until |
291 | * the next \c selectedElementChanged signal. |
292 | * |
293 | * Returns the pointer to the selected axis, or null. |
294 | * |
295 | * \sa selectedElement |
296 | */ |
297 | QAbstract3DAxis *Q3DGraphsWidgetItem::selectedAxis() const |
298 | { |
299 | Q_D(const Q3DGraphsWidgetItem); |
300 | return d->m_graphsItem->selectedAxis(); |
301 | } |
302 | |
303 | /*! |
304 | * Can be used to query the index of the selected custom item after receiving \c |
305 | * selectedElementChanged signal with Q3DGraphsWidgetItem::ElementType::CustomItem |
306 | * type. Selection is valid until the next \c selectedElementChanged signal. |
307 | * |
308 | * Returns the index of the selected custom item, or -1. |
309 | * |
310 | * \sa selectedElement |
311 | */ |
312 | qsizetype Q3DGraphsWidgetItem::selectedCustomItemIndex() const |
313 | { |
314 | Q_D(const Q3DGraphsWidgetItem); |
315 | return d->m_graphsItem->selectedCustomItemIndex(); |
316 | } |
317 | |
318 | /*! |
319 | * Can be used to get the selected custom item after receiving \c |
320 | * selectedElementChanged signal with Q3DGraphsWidgetItem::ElementType::CustomItem |
321 | * type. Ownership of the item remains with the graph. Selection is valid until |
322 | * the next \c selectedElementChanged signal. |
323 | * |
324 | * Returns the pointer to the selected custom item, or null. |
325 | * |
326 | * \sa selectedElement |
327 | */ |
328 | QCustom3DItem *Q3DGraphsWidgetItem::selectedCustomItem() const |
329 | { |
330 | Q_D(const Q3DGraphsWidgetItem); |
331 | return d->m_graphsItem->selectedCustomItem(); |
332 | } |
333 | |
334 | /*! |
335 | * \property Q3DGraphsWidgetItem::selectedElement |
336 | * \readonly |
337 | * |
338 | * \brief The element selected in the graph. |
339 | * |
340 | * This property can be used to query the selected element type. The type is |
341 | * valid until a new selection is made in the graph and the |
342 | * \c selectedElementChanged signal is emitted. |
343 | * |
344 | * The signal can be used for example for implementing custom input handlers, as |
345 | * demonstrated in the \l {Graph Gallery} example under \uicontrol {Scatter |
346 | * Graph} tab. |
347 | * |
348 | * \sa selectedLabelIndex(), selectedAxis(), selectedCustomItemIndex(), |
349 | * selectedCustomItem(), Q3DBarsWidgetItem::selectedSeries(), |
350 | * Q3DScatterWidgetItem::selectedSeries(), Q3DSurfaceWidgetItem::selectedSeries(), |
351 | * Q3DScene::setSelectionQueryPosition() |
352 | */ |
353 | QtGraphs3D::ElementType Q3DGraphsWidgetItem::selectedElement() const |
354 | { |
355 | Q_D(const Q3DGraphsWidgetItem); |
356 | return d->m_graphsItem->selectedElement(); |
357 | } |
358 | |
359 | /*! |
360 | * Renders current frame to an image of \a imageSize. |
361 | * Returns a shared pointer to grab result which can be used to access the |
362 | * rendered image when it's ready. Image is rendered with the current |
363 | * antialiasing settings. |
364 | * |
365 | * \sa QQuickItem::grabToImage() |
366 | */ |
367 | QSharedPointer<QQuickItemGrabResult> Q3DGraphsWidgetItem::renderToImage(QSize imageSize) const |
368 | { |
369 | QSize renderSize = imageSize; |
370 | |
371 | Q_D(const Q3DGraphsWidgetItem); |
372 | if (renderSize.isEmpty()) |
373 | renderSize = d->m_widget->size(); |
374 | |
375 | return d->m_graphsItem->grabToImage(targetSize: renderSize); |
376 | } |
377 | |
378 | QtGraphs3D::CameraPreset Q3DGraphsWidgetItem::cameraPreset() const |
379 | { |
380 | Q_D(const Q3DGraphsWidgetItem); |
381 | return d->m_graphsItem->cameraPreset(); |
382 | } |
383 | |
384 | void Q3DGraphsWidgetItem::setCameraPreset(QtGraphs3D::CameraPreset preset) |
385 | { |
386 | Q_D(Q3DGraphsWidgetItem); |
387 | d->m_graphsItem->setCameraPreset(preset); |
388 | } |
389 | /*! |
390 | * \property Q3DGraphsWidgetItem::cameraXRotation |
391 | * |
392 | * \brief The X-rotation angle of the camera around the target point in degrees. |
393 | */ |
394 | float Q3DGraphsWidgetItem::cameraXRotation() const |
395 | { |
396 | Q_D(const Q3DGraphsWidgetItem); |
397 | return d->m_graphsItem->cameraXRotation(); |
398 | } |
399 | |
400 | void Q3DGraphsWidgetItem::setCameraXRotation(float rotation) |
401 | { |
402 | Q_D(Q3DGraphsWidgetItem); |
403 | d->m_graphsItem->setCameraXRotation(rotation); |
404 | } |
405 | |
406 | /*! |
407 | * \property Q3DGraphsWidgetItem::cameraYRotation |
408 | * |
409 | * \brief The Y-rotation angle of the camera around the target point in degrees. |
410 | */ |
411 | float Q3DGraphsWidgetItem::cameraYRotation() const |
412 | { |
413 | Q_D(const Q3DGraphsWidgetItem); |
414 | return d->m_graphsItem->cameraYRotation(); |
415 | } |
416 | |
417 | void Q3DGraphsWidgetItem::setCameraYRotation(float rotation) |
418 | { |
419 | Q_D(Q3DGraphsWidgetItem); |
420 | d->m_graphsItem->setCameraYRotation(rotation); |
421 | } |
422 | |
423 | /*! |
424 | * \property Q3DGraphsWidgetItem::minCameraXRotation |
425 | * |
426 | * \brief The minimum X-rotation angle of the camera around the target point in degrees. |
427 | */ |
428 | float Q3DGraphsWidgetItem::minCameraXRotation() const |
429 | { |
430 | Q_D(const Q3DGraphsWidgetItem); |
431 | return d->m_graphsItem->minCameraXRotation(); |
432 | } |
433 | |
434 | void Q3DGraphsWidgetItem::setMinCameraXRotation(float rotation) |
435 | { |
436 | Q_D(Q3DGraphsWidgetItem); |
437 | d->m_graphsItem->setMinCameraXRotation(rotation); |
438 | } |
439 | |
440 | /*! |
441 | * \property Q3DGraphsWidgetItem::maxCameraXRotation |
442 | * |
443 | * \brief The maximum X-rotation angle of the camera around the target point in degrees. |
444 | */ |
445 | float Q3DGraphsWidgetItem::maxCameraXRotation() const |
446 | { |
447 | Q_D(const Q3DGraphsWidgetItem); |
448 | return d->m_graphsItem->maxCameraXRotation(); |
449 | } |
450 | |
451 | void Q3DGraphsWidgetItem::setMaxCameraXRotation(float rotation) |
452 | { |
453 | Q_D(Q3DGraphsWidgetItem); |
454 | d->m_graphsItem->setMaxCameraXRotation(rotation); |
455 | } |
456 | |
457 | /*! |
458 | * \property Q3DGraphsWidgetItem::minCameraYRotation |
459 | * |
460 | * \brief The minimum Y-rotation angle of the camera around the target point in degrees. |
461 | */ |
462 | float Q3DGraphsWidgetItem::minCameraYRotation() const |
463 | { |
464 | Q_D(const Q3DGraphsWidgetItem); |
465 | return d->m_graphsItem->minCameraYRotation(); |
466 | } |
467 | |
468 | void Q3DGraphsWidgetItem::setMinCameraYRotation(float rotation) |
469 | { |
470 | Q_D(Q3DGraphsWidgetItem); |
471 | d->m_graphsItem->setMinCameraYRotation(rotation); |
472 | } |
473 | |
474 | /*! |
475 | * \property Q3DGraphsWidgetItem::maxCameraYRotation |
476 | * |
477 | * \brief The maximum Y-rotation angle of the camera around the target point in degrees. |
478 | */ |
479 | float Q3DGraphsWidgetItem::maxCameraYRotation() const |
480 | { |
481 | Q_D(const Q3DGraphsWidgetItem); |
482 | return d->m_graphsItem->maxCameraYRotation(); |
483 | } |
484 | |
485 | void Q3DGraphsWidgetItem::setMaxCameraYRotation(float rotation) |
486 | { |
487 | Q_D(Q3DGraphsWidgetItem); |
488 | d->m_graphsItem->setMaxCameraYRotation(rotation); |
489 | } |
490 | |
491 | /*! |
492 | * \property Q3DGraphsWidgetItem::zoomAtTargetEnabled |
493 | * |
494 | * \brief Whether zooming should change the camera target so that the zoomed point |
495 | * of the graph stays at the same location after the zoom. |
496 | * |
497 | * Defaults to \c{true}. |
498 | */ |
499 | bool Q3DGraphsWidgetItem::isZoomAtTargetEnabled() const |
500 | { |
501 | Q_D(const Q3DGraphsWidgetItem); |
502 | return d->m_graphsItem->zoomAtTargetEnabled(); |
503 | } |
504 | |
505 | void Q3DGraphsWidgetItem::setZoomAtTargetEnabled(bool enable) |
506 | { |
507 | Q_D(Q3DGraphsWidgetItem); |
508 | d->m_graphsItem->setZoomAtTargetEnabled(enable); |
509 | } |
510 | |
511 | /*! |
512 | * \property Q3DGraphsWidgetItem::zoomEnabled |
513 | * |
514 | * \brief Whether this input handler allows graph zooming. |
515 | * |
516 | * Defaults to \c{true}. |
517 | */ |
518 | bool Q3DGraphsWidgetItem::isZoomEnabled() const |
519 | { |
520 | Q_D(const Q3DGraphsWidgetItem); |
521 | return d->m_graphsItem->zoomEnabled(); |
522 | } |
523 | |
524 | void Q3DGraphsWidgetItem::setZoomEnabled(bool enable) |
525 | { |
526 | Q_D(Q3DGraphsWidgetItem); |
527 | d->m_graphsItem->setZoomEnabled(enable); |
528 | } |
529 | |
530 | /*! |
531 | * \property Q3DGraphsWidgetItem::ambientLightStrength |
532 | * |
533 | * \brief The ambient light strength for the whole graph. |
534 | * |
535 | * This value determines how evenly and brightly the colors are shown throughout |
536 | * the graph regardless of the light position. |
537 | * |
538 | * The value must be between \c 0.0f and \c 1.0f. |
539 | */ |
540 | float Q3DGraphsWidgetItem::ambientLightStrength() const |
541 | { |
542 | Q_D(const Q3DGraphsWidgetItem); |
543 | return d->m_graphsItem->ambientLightStrength(); |
544 | } |
545 | |
546 | void Q3DGraphsWidgetItem::setAmbientLightStrength(float newAmbientLightStrength) |
547 | { |
548 | Q_D(Q3DGraphsWidgetItem); |
549 | d->m_graphsItem->setAmbientLightStrength(newAmbientLightStrength); |
550 | } |
551 | |
552 | /*! |
553 | * \property Q3DGraphsWidgetItem::lightStrength |
554 | * |
555 | * \brief The specular light strength for the whole graph. |
556 | * |
557 | * The value must be between \c 0.0f and \c 10.0f. |
558 | * |
559 | * This value affects the light specified in Q3DScene. |
560 | */ |
561 | float Q3DGraphsWidgetItem::lightStrength() const |
562 | { |
563 | Q_D(const Q3DGraphsWidgetItem); |
564 | return d->m_graphsItem->lightStrength(); |
565 | } |
566 | |
567 | void Q3DGraphsWidgetItem::setLightStrength(float newLightStrength) |
568 | { |
569 | Q_D(Q3DGraphsWidgetItem); |
570 | d->m_graphsItem->setLightStrength(newLightStrength); |
571 | } |
572 | |
573 | /*! |
574 | * \property Q3DGraphsWidgetItem::shadowStrength |
575 | * |
576 | * \brief The shadow strength for the whole graph. |
577 | * |
578 | * The higher the number, the darker the shadows will be. The value must be |
579 | * between \c 0.0 and \c 100.0. |
580 | * |
581 | * This value affects the light specified in Q3DScene. |
582 | */ |
583 | float Q3DGraphsWidgetItem::shadowStrength() const |
584 | { |
585 | Q_D(const Q3DGraphsWidgetItem); |
586 | return d->m_graphsItem->shadowStrength(); |
587 | } |
588 | |
589 | void Q3DGraphsWidgetItem::setShadowStrength(float newShadowStrength) |
590 | { |
591 | Q_D(Q3DGraphsWidgetItem); |
592 | d->m_graphsItem->setShadowStrength(newShadowStrength); |
593 | } |
594 | |
595 | /*! |
596 | * \property Q3DGraphsWidgetItem::lightColor |
597 | * |
598 | * \brief The color for the ambient and specular light. |
599 | * |
600 | * This value affects the light specified in Q3DScene. |
601 | */ |
602 | QColor Q3DGraphsWidgetItem::lightColor() const |
603 | { |
604 | Q_D(const Q3DGraphsWidgetItem); |
605 | return d->m_graphsItem->lightColor(); |
606 | } |
607 | |
608 | void Q3DGraphsWidgetItem::setLightColor(QColor newLightColor) |
609 | { |
610 | Q_D(Q3DGraphsWidgetItem); |
611 | d->m_graphsItem->setLightColor(newLightColor); |
612 | } |
613 | |
614 | /*! |
615 | * \property Q3DGraphsWidgetItem::gridLineType |
616 | * |
617 | * \brief Whether the grid lines type is QtGraphs3D::GridLineType::Shader or |
618 | * QtGraphs3D::GridLineType::Geometry. |
619 | * |
620 | * This value affects all grid lines. |
621 | * |
622 | * \sa QtGraphs3D::GridLineType |
623 | */ |
624 | QtGraphs3D::GridLineType Q3DGraphsWidgetItem::gridLineType() const |
625 | { |
626 | Q_D(const Q3DGraphsWidgetItem); |
627 | return d->m_graphsItem->gridLineType(); |
628 | } |
629 | |
630 | void Q3DGraphsWidgetItem::setGridLineType(const QtGraphs3D::GridLineType &gridLineType) |
631 | { |
632 | Q_D(Q3DGraphsWidgetItem); |
633 | d->m_graphsItem->setGridLineType(gridLineType); |
634 | } |
635 | |
636 | /*! |
637 | * Sets the given \a widget instance to be used as the \l QQuickWidget for the widget item. |
638 | * The graph is set as the content of the QQuickWidget. |
639 | * |
640 | * Graphs can only be rendered in widget applications using QQuickWidgets. |
641 | * |
642 | * Usage example: |
643 | * \code |
644 | * QQuickWidget quickwidget; |
645 | * Q3DBarsWidgetItem graph; |
646 | * graph.setWidget(&quickwidget); |
647 | * \endcode |
648 | */ |
649 | void Q3DGraphsWidgetItem::setWidget(QQuickWidget *widget) |
650 | { |
651 | Q_D(Q3DGraphsWidgetItem); |
652 | d->m_widget = widget; |
653 | if (d->m_widget != nullptr) { |
654 | d->m_widget->installEventFilter(filterObj: this); |
655 | d->createGraph(); |
656 | } |
657 | } |
658 | |
659 | /*! |
660 | * Returns a pointer to the \l QQuickWidget instance that has been set for the widget item. |
661 | */ |
662 | QQuickWidget *Q3DGraphsWidgetItem::widget() const |
663 | { |
664 | Q_D(const Q3DGraphsWidgetItem); |
665 | return d->m_widget; |
666 | } |
667 | |
668 | /*! |
669 | * \property Q3DGraphsWidgetItem::selectionEnabled |
670 | * |
671 | * \brief Whether this input handler allows selection from the graph. |
672 | * |
673 | * Defaults to \c{true}. |
674 | */ |
675 | bool Q3DGraphsWidgetItem::isSelectionEnabled() const |
676 | { |
677 | Q_D(const Q3DGraphsWidgetItem); |
678 | return d->m_graphsItem->selectionEnabled(); |
679 | } |
680 | |
681 | void Q3DGraphsWidgetItem::setSelectionEnabled(bool enable) |
682 | { |
683 | Q_D(Q3DGraphsWidgetItem); |
684 | d->m_graphsItem->setSelectionEnabled(enable); |
685 | } |
686 | |
687 | /*! |
688 | * \property Q3DGraphsWidgetItem::rotationEnabled |
689 | * |
690 | * \brief Whether this input handler allows graph rotation. |
691 | * |
692 | * Defaults to \c{true}. |
693 | */ |
694 | bool Q3DGraphsWidgetItem::isRotationEnabled() const |
695 | { |
696 | Q_D(const Q3DGraphsWidgetItem); |
697 | return d->m_graphsItem->rotationEnabled(); |
698 | } |
699 | |
700 | void Q3DGraphsWidgetItem::setRotationEnabled(bool enable) |
701 | { |
702 | Q_D(Q3DGraphsWidgetItem); |
703 | d->m_graphsItem->setRotationEnabled(enable); |
704 | } |
705 | |
706 | void Q3DGraphsWidgetItem::setDefaultInputHandler() |
707 | { |
708 | Q_D(Q3DGraphsWidgetItem); |
709 | d->m_graphsItem->setDefaultInputHandler(); |
710 | } |
711 | |
712 | void Q3DGraphsWidgetItem::unsetDefaultInputHandler() |
713 | { |
714 | Q_D(Q3DGraphsWidgetItem); |
715 | d->m_graphsItem->unsetDefaultInputHandler(); |
716 | } |
717 | |
718 | void Q3DGraphsWidgetItem::unsetDefaultTapHandler() |
719 | { |
720 | Q_D(Q3DGraphsWidgetItem); |
721 | d->m_graphsItem->unsetDefaultTapHandler(); |
722 | } |
723 | |
724 | void Q3DGraphsWidgetItem::unsetDefaultDragHandler() |
725 | { |
726 | Q_D(Q3DGraphsWidgetItem); |
727 | d->m_graphsItem->unsetDefaultDragHandler(); |
728 | } |
729 | |
730 | void Q3DGraphsWidgetItem::unsetDefaultWheelHandler() |
731 | { |
732 | Q_D(Q3DGraphsWidgetItem); |
733 | d->m_graphsItem->unsetDefaultWheelHandler(); |
734 | } |
735 | |
736 | void Q3DGraphsWidgetItem::unsetDefaultPinchHandler() |
737 | { |
738 | Q_D(Q3DGraphsWidgetItem); |
739 | d->m_graphsItem->unsetDefaultPinchHandler(); |
740 | } |
741 | |
742 | void Q3DGraphsWidgetItem::setDragButton(Qt::MouseButtons button) |
743 | { |
744 | Q_D(Q3DGraphsWidgetItem); |
745 | d->m_graphsItem->setDragButton(button); |
746 | } |
747 | |
748 | /*! |
749 | * \property Q3DGraphsWidgetItem::cameraZoomLevel |
750 | * |
751 | * \brief The camera zoom level in percentage. |
752 | * |
753 | * The default value of \c{100.0f} means there is no zoom in or out set in the |
754 | * camera. The value is limited by the minCameraZoomLevel and maxCameraZoomLevel |
755 | * properties. |
756 | * |
757 | * \sa minCameraZoomLevel, maxCameraZoomLevel |
758 | */ |
759 | float Q3DGraphsWidgetItem::cameraZoomLevel() const |
760 | { |
761 | Q_D(const Q3DGraphsWidgetItem); |
762 | return d->m_graphsItem->cameraZoomLevel(); |
763 | } |
764 | |
765 | void Q3DGraphsWidgetItem::setCameraZoomLevel(float level) |
766 | { |
767 | Q_D(Q3DGraphsWidgetItem); |
768 | d->m_graphsItem->setCameraZoomLevel(level); |
769 | d->m_graphsItem->update(); |
770 | } |
771 | |
772 | /*! |
773 | * \property Q3DGraphsWidgetItem::minCameraZoomLevel |
774 | * |
775 | * \brief The minimum allowed camera zoom level. |
776 | * |
777 | * If the minimum level is set to a new value that is higher than the existing |
778 | * maximum level, the maximum level is adjusted to the new minimum as well. |
779 | * If the current zoomLevel is outside the new bounds, it is adjusted as well. |
780 | * The minCameraZoomLevel cannot be set below \c{1.0f}. |
781 | * Defaults to \c{10.0f}. |
782 | * |
783 | * \sa cameraZoomLevel, maxCameraZoomLevel |
784 | */ |
785 | float Q3DGraphsWidgetItem::minCameraZoomLevel() const |
786 | { |
787 | Q_D(const Q3DGraphsWidgetItem); |
788 | return d->m_graphsItem->minCameraZoomLevel(); |
789 | } |
790 | |
791 | void Q3DGraphsWidgetItem::setMinCameraZoomLevel(float level) |
792 | { |
793 | Q_D(Q3DGraphsWidgetItem); |
794 | d->m_graphsItem->setMinCameraZoomLevel(level); |
795 | } |
796 | |
797 | /*! |
798 | * \property Q3DGraphsWidgetItem::maxCameraZoomLevel |
799 | * |
800 | * \brief The maximum allowed camera zoom level. |
801 | * |
802 | * If the maximum level is set to a new value that is lower than the existing |
803 | * minimum level, the minimum level is adjusted to the new maximum as well. |
804 | * If the current cameraZoomLevel is outside the new bounds, it is adjusted as |
805 | * well. Defaults to \c{500.0f}. |
806 | * |
807 | * \sa cameraZoomLevel, minCameraZoomLevel |
808 | */ |
809 | float Q3DGraphsWidgetItem::maxCameraZoomLevel() const |
810 | { |
811 | Q_D(const Q3DGraphsWidgetItem); |
812 | return d->m_graphsItem->maxCameraZoomLevel(); |
813 | } |
814 | |
815 | void Q3DGraphsWidgetItem::setMaxCameraZoomLevel(float level) |
816 | { |
817 | Q_D(Q3DGraphsWidgetItem); |
818 | d->m_graphsItem->setMaxCameraZoomLevel(level); |
819 | } |
820 | |
821 | /*! |
822 | * \property Q3DGraphsWidgetItem::cameraTargetPosition |
823 | * |
824 | * \brief The camera target position as a vector or vertex in the 3D space. |
825 | * |
826 | * Defaults to \c {QVector3D(0.0, 0.0, 0.0)}. |
827 | * |
828 | * Valid coordinate values are between \c{-1.0...1.0}, where the edge values |
829 | * indicate the edges of the corresponding axis range. Any values outside this |
830 | * range are clamped to the edge. |
831 | */ |
832 | QVector3D Q3DGraphsWidgetItem::cameraTargetPosition() const |
833 | { |
834 | Q_D(const Q3DGraphsWidgetItem); |
835 | return d->m_graphsItem->cameraTargetPosition(); |
836 | } |
837 | |
838 | void Q3DGraphsWidgetItem::setCameraTargetPosition(QVector3D target) |
839 | { |
840 | Q_D(Q3DGraphsWidgetItem); |
841 | |
842 | QVector3D newTarget = target; |
843 | |
844 | if (newTarget.x() < -1.0f) |
845 | newTarget.setX(-1.0f); |
846 | else if (newTarget.x() > 1.0f) |
847 | newTarget.setX(1.0f); |
848 | |
849 | if (newTarget.y() < -1.0f) |
850 | newTarget.setY(-1.0f); |
851 | else if (newTarget.y() > 1.0f) |
852 | newTarget.setY(1.0f); |
853 | |
854 | if (newTarget.z() < -1.0f) |
855 | newTarget.setZ(-1.0f); |
856 | else if (newTarget.z() > 1.0f) |
857 | newTarget.setZ(1.0f); |
858 | |
859 | if (d->m_graphsItem->cameraTargetPosition() != newTarget) { |
860 | if (d->m_graphsItem->cameraPreset() != QtGraphs3D::CameraPreset::NoPreset) |
861 | d->m_graphsItem->setCameraPreset(QtGraphs3D::CameraPreset::NoPreset); |
862 | d->m_graphsItem->setCameraTargetPosition(newTarget); |
863 | } |
864 | } |
865 | |
866 | /*! |
867 | * \property Q3DGraphsWidgetItem::wrapCameraXRotation |
868 | * |
869 | * \brief The behavior of the minimum and maximum limits in the X-rotation. |
870 | * |
871 | * If set to \c true, the X-rotation of the camera is wrapped from minimum to |
872 | * maximum and from maximum to minimum. If set to \c false, the X-rotation of |
873 | * the camera is limited to the sector determined by the minimum and maximum |
874 | * values. Set to \c true by default. |
875 | */ |
876 | bool Q3DGraphsWidgetItem::wrapCameraXRotation() const |
877 | { |
878 | Q_D(const Q3DGraphsWidgetItem); |
879 | return d->m_graphsItem->wrapCameraXRotation(); |
880 | } |
881 | |
882 | void Q3DGraphsWidgetItem::setWrapCameraXRotation(bool wrap) |
883 | { |
884 | Q_D(Q3DGraphsWidgetItem); |
885 | d->m_graphsItem->setWrapCameraXRotation(wrap); |
886 | } |
887 | |
888 | /*! |
889 | * \property Q3DGraphsWidgetItem::wrapCameraYRotation |
890 | * |
891 | * \brief The behavior of the minimum and maximum limits in the Y-rotation. |
892 | * |
893 | * If \c true, the Y-rotation of the camera is wrapped from minimum to maximum |
894 | * and from maximum to minimum. If \c false, the Y-rotation of the camera is |
895 | * limited to the sector determined by the minimum and maximum values. |
896 | * Set to \c true by default. |
897 | */ |
898 | bool Q3DGraphsWidgetItem::wrapCameraYRotation() const |
899 | { |
900 | Q_D(const Q3DGraphsWidgetItem); |
901 | return d->m_graphsItem->wrapCameraYRotation(); |
902 | } |
903 | |
904 | void Q3DGraphsWidgetItem::setWrapCameraYRotation(bool wrap) |
905 | { |
906 | Q_D(Q3DGraphsWidgetItem); |
907 | d->m_graphsItem->setWrapCameraYRotation(wrap); |
908 | } |
909 | |
910 | /*! |
911 | * Utility function that sets the camera rotations and distance.\a horizontal |
912 | * and \a vertical define the camera rotations to be used. Optional \a zoom |
913 | * parameter can be given to set the zoom percentage of the camera within the |
914 | * bounds defined by minCameraZoomLevel and maxCameraZoomLevel properties. |
915 | */ |
916 | void Q3DGraphsWidgetItem::setCameraPosition(float horizontal, float vertical, float zoom) |
917 | { |
918 | Q_D(Q3DGraphsWidgetItem); |
919 | d->m_graphsItem->setCameraPosition(horizontal, vertical, zoom); |
920 | } |
921 | |
922 | /*! |
923 | * \property Q3DGraphsWidgetItem::msaaSamples |
924 | * |
925 | * \brief The number of used samples in MSAA. |
926 | * |
927 | * Sets the number of used MSAA samples to \a samples. The number of samples can |
928 | * be either 0, 2, 4, or 8. |
929 | * |
930 | */ |
931 | int Q3DGraphsWidgetItem::msaaSamples() const |
932 | { |
933 | Q_D(const Q3DGraphsWidgetItem); |
934 | return d->m_graphsItem->msaaSamples(); |
935 | } |
936 | |
937 | void Q3DGraphsWidgetItem::setMsaaSamples(int samples) |
938 | { |
939 | Q_D(Q3DGraphsWidgetItem); |
940 | d->m_graphsItem->setMsaaSamples(samples); |
941 | } |
942 | |
943 | void Q3DGraphsWidgetItem::doPicking(QPoint point) |
944 | { |
945 | Q_D(Q3DGraphsWidgetItem); |
946 | d->m_graphsItem->doPicking(point); |
947 | } |
948 | |
949 | /*! |
950 | * \property Q3DGraphsWidgetItem::measureFps |
951 | * |
952 | * \brief Whether rendering is done continuously instead of on demand. |
953 | * |
954 | * If \c {true}, rendering is continuous and the value of the currentFps |
955 | * property is updated. Defaults to \c{false}. |
956 | * |
957 | * \sa currentFps |
958 | */ |
959 | void Q3DGraphsWidgetItem::setMeasureFps(bool enable) |
960 | { |
961 | Q_D(Q3DGraphsWidgetItem); |
962 | |
963 | d->m_graphsItem->setMeasureFps(enable); |
964 | if (enable) { |
965 | QObject::connect(sender: d->m_graphsItem.get(), |
966 | signal: &QQuickGraphsItem::currentFpsChanged, |
967 | context: this, |
968 | slot: &Q3DGraphsWidgetItem::currentFpsChanged); |
969 | } else { |
970 | QObject::disconnect(sender: d->m_graphsItem.get(), |
971 | signal: &QQuickGraphsItem::currentFpsChanged, |
972 | receiver: this, |
973 | slot: &Q3DGraphsWidgetItem::currentFpsChanged); |
974 | } |
975 | } |
976 | |
977 | bool Q3DGraphsWidgetItem::measureFps() const |
978 | { |
979 | Q_D(const Q3DGraphsWidgetItem); |
980 | return d->m_graphsItem->measureFps(); |
981 | } |
982 | |
983 | /*! |
984 | * \property Q3DGraphsWidgetItem::currentFps |
985 | * |
986 | * \brief The rendering results for the last second. |
987 | * |
988 | * The results are stored in this read-only property when FPS measuring is |
989 | * enabled. It takes at least a second before this value is updated after |
990 | * measuring is activated. |
991 | * |
992 | * \sa measureFps |
993 | */ |
994 | int Q3DGraphsWidgetItem::currentFps() const |
995 | { |
996 | Q_D(const Q3DGraphsWidgetItem); |
997 | return d->m_graphsItem->currentFps(); |
998 | } |
999 | |
1000 | /*! |
1001 | * \property Q3DGraphsWidgetItem::orthoProjection |
1002 | * |
1003 | * \brief Whether orthographic projection is used for displaying the graph. |
1004 | * |
1005 | * Defaults to \c{false}. |
1006 | * \note Shadows will be disabled when set to \c{true}. |
1007 | * |
1008 | * \sa QAbstract3DAxis::labelAutoAngle, |
1009 | */ |
1010 | void Q3DGraphsWidgetItem::setOrthoProjection(bool enable) |
1011 | { |
1012 | Q_D(Q3DGraphsWidgetItem); |
1013 | d->m_graphsItem->setOrthoProjection(enable); |
1014 | } |
1015 | |
1016 | bool Q3DGraphsWidgetItem::isOrthoProjection() const |
1017 | { |
1018 | Q_D(const Q3DGraphsWidgetItem); |
1019 | return d->m_graphsItem->isOrthoProjection(); |
1020 | } |
1021 | |
1022 | /*! |
1023 | * \property Q3DGraphsWidgetItem::aspectRatio |
1024 | * |
1025 | * \brief The ratio of the graph scaling between the longest axis on the |
1026 | * horizontal plane and the y-axis. |
1027 | * |
1028 | * Defaults to \c{2.0}. |
1029 | * |
1030 | * \note Has no effect on Q3DBarsWidgetItem. |
1031 | * |
1032 | * \sa horizontalAspectRatio |
1033 | */ |
1034 | void Q3DGraphsWidgetItem::setAspectRatio(qreal ratio) |
1035 | { |
1036 | Q_D(Q3DGraphsWidgetItem); |
1037 | d->m_graphsItem->setAspectRatio(ratio); |
1038 | } |
1039 | |
1040 | qreal Q3DGraphsWidgetItem::aspectRatio() const |
1041 | { |
1042 | Q_D(const Q3DGraphsWidgetItem); |
1043 | return d->m_graphsItem->aspectRatio(); |
1044 | } |
1045 | |
1046 | /*! |
1047 | * \property Q3DGraphsWidgetItem::optimizationHint |
1048 | * |
1049 | * \brief Specifies whether the default or legacy mode is used for rendering |
1050 | * optimization. |
1051 | * |
1052 | * The default mode uses instanced rendering, and provides the full feature set |
1053 | * at the best level of performance on most systems. The static mode optimizes |
1054 | * graph rendering and is ideal for large non-changing data sets. It is slower |
1055 | * with dynamic data changes and item rotations. Selection is not optimized, so |
1056 | * using the static mode with massive data sets is not advisable. Static |
1057 | * optimization works only on scatter graphs. Legacy mode renders all items in |
1058 | * th graph individually, without instancing. It should be used only if default |
1059 | * mode does not work, i.e. if the target system does not support instancing. |
1060 | * Defaults to \l{QtGraphs3D::OptimizationHint::Default}. |
1061 | * |
1062 | * \note On some environments, large graphs using static optimization may not |
1063 | * render, because all of the items are rendered using a single draw call, and |
1064 | * different graphics drivers support different maximum vertice counts per call. |
1065 | * This is mostly an issue on 32bit and OpenGL ES2 platforms. |
1066 | * To work around this issue, choose an item mesh with a low vertex count or use |
1067 | * the point mesh. |
1068 | * |
1069 | * \sa QAbstract3DSeries::mesh |
1070 | */ |
1071 | void Q3DGraphsWidgetItem::setOptimizationHint(QtGraphs3D::OptimizationHint hint) |
1072 | { |
1073 | Q_D(Q3DGraphsWidgetItem); |
1074 | d->m_graphsItem->setOptimizationHint(hint); |
1075 | } |
1076 | |
1077 | QtGraphs3D::OptimizationHint Q3DGraphsWidgetItem::optimizationHint() const |
1078 | { |
1079 | Q_D(const Q3DGraphsWidgetItem); |
1080 | return d->m_graphsItem->optimizationHint(); |
1081 | } |
1082 | |
1083 | /*! |
1084 | * \property Q3DGraphsWidgetItem::polar |
1085 | * |
1086 | * \brief Whether horizontal axes are changed into polar axes. |
1087 | * |
1088 | * If \c {true}, the x-axis becomes the angular axis and the z-axis becomes the |
1089 | * radial axis. |
1090 | * Polar mode is not available for bar graphs. |
1091 | * |
1092 | * Defaults to \c{false}. |
1093 | * |
1094 | * \sa orthoProjection, radialLabelOffset |
1095 | */ |
1096 | void Q3DGraphsWidgetItem::setPolar(bool enable) |
1097 | { |
1098 | Q_D(Q3DGraphsWidgetItem); |
1099 | d->m_graphsItem->setPolar(enable); |
1100 | } |
1101 | |
1102 | bool Q3DGraphsWidgetItem::isPolar() const |
1103 | { |
1104 | Q_D(const Q3DGraphsWidgetItem); |
1105 | return d->m_graphsItem->isPolar(); |
1106 | } |
1107 | |
1108 | /*! |
1109 | * \property Q3DGraphsWidgetItem::labelMargin |
1110 | * |
1111 | * \brief This property specifies the margin for the placement of the axis labels. |
1112 | * |
1113 | * Negative values place the labels inside the plot-area while positive values |
1114 | * place them outside the plot-area. Label automatic rotation is disabled when |
1115 | * the value is negative. Defaults to \c 0.1 |
1116 | * |
1117 | * \sa QAbstract3DAxis::labelAutoAngle |
1118 | * |
1119 | */ |
1120 | void Q3DGraphsWidgetItem::setLabelMargin(float margin) |
1121 | { |
1122 | Q_D(Q3DGraphsWidgetItem); |
1123 | d->m_graphsItem->setLabelMargin(margin); |
1124 | } |
1125 | |
1126 | float Q3DGraphsWidgetItem::labelMargin() const |
1127 | { |
1128 | Q_D(const Q3DGraphsWidgetItem); |
1129 | return d->m_graphsItem->labelMargin(); |
1130 | } |
1131 | /*! |
1132 | * \property Q3DGraphsWidgetItem::radialLabelOffset |
1133 | * |
1134 | * \brief The normalized horizontal offset for the axis labels of the radial |
1135 | * polar axis. |
1136 | * |
1137 | * The value \c 0.0 indicates that the labels should be drawn next to the |
1138 | * 0-angle angular axis grid line. The value \c 1.0 indicates that the labels |
1139 | * are drawn in their usual place at the edge of the graph background. Defaults |
1140 | * to \c 1.0. |
1141 | * |
1142 | * This property is ignored if the \l polar property value is \c{false}. |
1143 | * |
1144 | * \sa polar |
1145 | */ |
1146 | void Q3DGraphsWidgetItem::setRadialLabelOffset(float offset) |
1147 | { |
1148 | Q_D(Q3DGraphsWidgetItem); |
1149 | d->m_graphsItem->setRadialLabelOffset(offset); |
1150 | } |
1151 | |
1152 | float Q3DGraphsWidgetItem::radialLabelOffset() const |
1153 | { |
1154 | Q_D(const Q3DGraphsWidgetItem); |
1155 | return d->m_graphsItem->radialLabelOffset(); |
1156 | } |
1157 | |
1158 | /*! |
1159 | * \property Q3DGraphsWidgetItem::horizontalAspectRatio |
1160 | * |
1161 | * \brief The ratio of the graph scaling between the x-axis and z-axis. |
1162 | * |
1163 | * The value of \c 0.0 indicates automatic scaling according to axis ranges. |
1164 | * Defaults to \c{0.0}. |
1165 | * |
1166 | * Has no effect on Q3DBarsWidgetItem, which handles scaling on the horizontal plane via |
1167 | * the \l{Q3DBarsWidgetItem::barThickness}{barThickness} and |
1168 | * \l{Q3DBarsWidgetItem::barSpacing}{barSpacing} properties. Polar graphs also ignore this |
1169 | * property. |
1170 | * |
1171 | * \sa aspectRatio, polar, Q3DBarsWidgetItem::barThickness, Q3DBarsWidgetItem::barSpacing |
1172 | */ |
1173 | void Q3DGraphsWidgetItem::setHorizontalAspectRatio(qreal ratio) |
1174 | { |
1175 | Q_D(Q3DGraphsWidgetItem); |
1176 | d->m_graphsItem->setHorizontalAspectRatio(ratio); |
1177 | } |
1178 | |
1179 | qreal Q3DGraphsWidgetItem::horizontalAspectRatio() const |
1180 | { |
1181 | Q_D(const Q3DGraphsWidgetItem); |
1182 | return d->m_graphsItem->horizontalAspectRatio(); |
1183 | } |
1184 | |
1185 | /*! |
1186 | * \property Q3DGraphsWidgetItem::locale |
1187 | * |
1188 | * \brief The locale used for formatting various numeric labels. |
1189 | * |
1190 | * Defaults to the \c{"C"} locale. |
1191 | * |
1192 | * \sa QValue3DAxis::labelFormat |
1193 | */ |
1194 | void Q3DGraphsWidgetItem::setLocale(const QLocale &locale) |
1195 | { |
1196 | Q_D(Q3DGraphsWidgetItem); |
1197 | d->m_graphsItem->setLocale(locale); |
1198 | } |
1199 | |
1200 | QLocale Q3DGraphsWidgetItem::locale() const |
1201 | { |
1202 | Q_D(const Q3DGraphsWidgetItem); |
1203 | return d->m_graphsItem->locale(); |
1204 | } |
1205 | |
1206 | /*! |
1207 | * \property Q3DGraphsWidgetItem::queriedGraphPosition |
1208 | * \readonly |
1209 | * |
1210 | * \brief The latest queried graph position values along each axis. |
1211 | * |
1212 | * This read-only property contains the results from |
1213 | * Q3DScene::graphPositionQuery. The values are normalized to the range \c{[-1, |
1214 | * 1]}. If the queried position was outside the graph bounds, the values will |
1215 | * not reflect the real position, but will instead indicate an undefined |
1216 | * position outside the range \c{[-1, 1]}. The value will be undefined until a |
1217 | * query is made. |
1218 | * |
1219 | * There is no single correct 3D coordinate to match a particular screen |
1220 | * position, so to be consistent, the queries are always done against the inner |
1221 | * sides of an invisible box surrounding the graph. |
1222 | * |
1223 | * \note Bar graphs only allow querying graph position at the graph floor level, |
1224 | * so the y-value is always zero for bar graphs and the valid queries can be |
1225 | * only made at screen positions that contain the floor of the graph. |
1226 | * |
1227 | * \sa Q3DScene::graphPositionQuery |
1228 | */ |
1229 | QVector3D Q3DGraphsWidgetItem::queriedGraphPosition() const |
1230 | { |
1231 | Q_D(const Q3DGraphsWidgetItem); |
1232 | return d->m_graphsItem->queriedGraphPosition(); |
1233 | } |
1234 | |
1235 | /*! |
1236 | * \property Q3DGraphsWidgetItem::margin |
1237 | * |
1238 | * \brief The absolute value used for the space left between the edge of the |
1239 | * plottable graph area and the edge of the graph background. |
1240 | * |
1241 | * If the margin value is negative, the margins are determined automatically and |
1242 | * can vary according to the size of the items in the series and the type of the |
1243 | * graph. The value is interpreted as a fraction of the y-axis range if the |
1244 | * graph aspect ratios have not been changed from the default values. Defaults |
1245 | * to \c{-1.0}. |
1246 | * |
1247 | * \note Setting a smaller margin for a scatter graph than the automatically |
1248 | * determined margin can cause the scatter items at the edges of the graph to |
1249 | * overlap with the graph background. |
1250 | * |
1251 | * \note On scatter and surface graphs, if the margin is small in comparison to |
1252 | * the axis label size, the positions of the edge labels of the axes are |
1253 | * adjusted to avoid overlap with the edge labels of the neighboring axes. |
1254 | */ |
1255 | void Q3DGraphsWidgetItem::setMargin(qreal margin) |
1256 | { |
1257 | Q_D(Q3DGraphsWidgetItem); |
1258 | d->m_graphsItem->setMargin(margin); |
1259 | } |
1260 | |
1261 | qreal Q3DGraphsWidgetItem::margin() const |
1262 | { |
1263 | Q_D(const Q3DGraphsWidgetItem); |
1264 | return d->m_graphsItem->margin(); |
1265 | } |
1266 | |
1267 | /*! |
1268 | * \internal |
1269 | */ |
1270 | bool Q3DGraphsWidgetItem::event(QEvent *event) |
1271 | { |
1272 | switch (event->type()) { |
1273 | case QEvent::TouchBegin: |
1274 | case QEvent::TouchCancel: |
1275 | case QEvent::TouchUpdate: |
1276 | case QEvent::TouchEnd: { |
1277 | Q_D(Q3DGraphsWidgetItem); |
1278 | d->m_graphsItem->touchEvent(event: static_cast<QTouchEvent *>(event)); |
1279 | } |
1280 | return true; |
1281 | default: |
1282 | return QObject::event(event); |
1283 | } |
1284 | } |
1285 | |
1286 | bool Q3DGraphsWidgetItem::eventFilter(QObject *obj, QEvent *event) |
1287 | { |
1288 | if (event->type() == QEvent::Resize) { |
1289 | Q_D(Q3DGraphsWidgetItem); |
1290 | auto ev = static_cast<QResizeEvent *>(event); |
1291 | if (d->m_graphsItem) { |
1292 | Q3DScene *scene = (Q3DScene *) d->m_graphsItem->scene(); |
1293 | scene->d_func()->setWindowSize(QSize(ev->size().width(), ev->size().height())); |
1294 | d->m_graphsItem->resizeViewports(viewportSize: ev->size()); |
1295 | if (d->m_graphsItem->sliceView() && d->m_graphsItem->sliceView()->isVisible()) |
1296 | d->m_graphsItem->minimizeMainGraph(); |
1297 | d->m_graphsItem->updateSubViews(); |
1298 | } |
1299 | return false; |
1300 | } |
1301 | return QObject::eventFilter(watched: obj, event); |
1302 | } |
1303 | |
1304 | /*! |
1305 | * \internal |
1306 | */ |
1307 | |
1308 | void Q3DGraphsWidgetItemPrivate::onWheel(QQuickWheelEvent *event) |
1309 | { |
1310 | Q_Q(Q3DGraphsWidgetItem); |
1311 | |
1312 | QWheelEvent *ev = new QWheelEvent(QPointF(event->x(), event->y()), |
1313 | QPointF(event->x(), event->y()), |
1314 | event->pixelDelta(), |
1315 | event->angleDelta(), |
1316 | static_cast<Qt::MouseButton>(event->buttons()), |
1317 | static_cast<Qt::KeyboardModifier>(event->modifiers()), |
1318 | event->phase(), |
1319 | event->inverted(), |
1320 | Qt::MouseEventSynthesizedBySystem, |
1321 | event->pointingDevice()); |
1322 | emit q->wheel(event: ev); |
1323 | } |
1324 | |
1325 | void Q3DGraphsWidgetItemPrivate::createGraph() |
1326 | { |
1327 | Q_Q(Q3DGraphsWidgetItem); |
1328 | if (m_widget == nullptr) |
1329 | return; |
1330 | m_widget->setResizeMode(QQuickWidget::SizeRootObjectToView); |
1331 | |
1332 | #ifdef Q_OS_DARWIN |
1333 | // Take care of widget users (or CI) wanting to use OpenGL backend on macOS |
1334 | if (QQuickWindow::graphicsApi() == QSGRendererInterface::OpenGL) |
1335 | QSurfaceFormat::setDefaultFormat(QQuick3D::idealSurfaceFormat(4)); |
1336 | #endif |
1337 | |
1338 | const QString qmlData = QLatin1StringView(R"QML( |
1339 | import QtQuick; |
1340 | import QtGraphs; |
1341 | |
1342 | %1 |
1343 | { |
1344 | anchors.fill: parent; |
1345 | } |
1346 | )QML" ) |
1347 | .arg(args&: m_graphType); |
1348 | QQmlComponent *component = new QQmlComponent(m_widget->engine(), q); |
1349 | component->setData(qmlData.toUtf8(), baseUrl: QUrl()); |
1350 | m_graphsItem.reset(p: qobject_cast<QQuickGraphsItem *>(object: component->create())); |
1351 | m_widget->setContent(url: component->url(), component, item: m_graphsItem.get()); |
1352 | |
1353 | QObject::connect(sender: m_graphsItem.get(), |
1354 | signal: &QQuickGraphsItem::selectedElementChanged, |
1355 | context: q, |
1356 | slot: &Q3DGraphsWidgetItem::selectedElementChanged); |
1357 | QObject::connect(sender: m_graphsItem.get(), |
1358 | signal: &QQuickGraphsItem::msaaSamplesChanged, |
1359 | context: q, |
1360 | slot: &Q3DGraphsWidgetItem::msaaSamplesChanged); |
1361 | |
1362 | QObject::connect(sender: m_graphsItem.get(), |
1363 | signal: &QQuickGraphsItem::tapped, |
1364 | context: q, |
1365 | slot: &Q3DGraphsWidgetItem::tapped); |
1366 | QObject::connect(sender: m_graphsItem.get(), |
1367 | signal: &QQuickGraphsItem::doubleTapped, |
1368 | context: q, |
1369 | slot: &Q3DGraphsWidgetItem::doubleTapped); |
1370 | QObject::connect(sender: m_graphsItem.get(), |
1371 | signal: &QQuickGraphsItem::longPressed, |
1372 | context: q, |
1373 | slot: &Q3DGraphsWidgetItem::longPressed); |
1374 | QObject::connect(sender: m_graphsItem.get(), |
1375 | signal: &QQuickGraphsItem::dragged, |
1376 | context: q, |
1377 | slot: &Q3DGraphsWidgetItem::dragged); |
1378 | QObjectPrivate::connect(sender: m_graphsItem.get(), |
1379 | signal: &QQuickGraphsItem::wheel, |
1380 | receiverPrivate: this, |
1381 | slot: &Q3DGraphsWidgetItemPrivate::onWheel); |
1382 | QObject::connect(sender: m_graphsItem.get(), |
1383 | signal: &QQuickGraphsItem::pinch, |
1384 | context: q, |
1385 | slot: &Q3DGraphsWidgetItem::pinch); |
1386 | QObject::connect(sender: m_graphsItem.get(), |
1387 | signal: &QQuickGraphsItem::mouseMove, |
1388 | context: q, |
1389 | slot: &Q3DGraphsWidgetItem::mouseMove); |
1390 | |
1391 | QObject::connect(sender: m_graphsItem.get(), |
1392 | signal: &QQuickGraphsItem::zoomEnabledChanged, |
1393 | context: q, |
1394 | slot: &Q3DGraphsWidgetItem::zoomEnabledChanged); |
1395 | QObject::connect(sender: m_graphsItem.get(), |
1396 | signal: &QQuickGraphsItem::zoomAtTargetEnabledChanged, |
1397 | context: q, |
1398 | slot: &Q3DGraphsWidgetItem::zoomAtTargetEnabledChanged); |
1399 | QObject::connect(sender: m_graphsItem.get(), |
1400 | signal: &QQuickGraphsItem::rotationEnabledChanged, |
1401 | context: q, |
1402 | slot: &Q3DGraphsWidgetItem::rotationEnabledChanged); |
1403 | QObject::connect(sender: m_graphsItem.get(), |
1404 | signal: &QQuickGraphsItem::selectionEnabledChanged, |
1405 | context: q, |
1406 | slot: &Q3DGraphsWidgetItem::selectionEnabledChanged); |
1407 | QObject::connect(sender: m_graphsItem.get(), |
1408 | signal: &QQuickGraphsItem::queriedGraphPositionChanged, |
1409 | context: q, |
1410 | slot: &Q3DGraphsWidgetItem::queriedGraphPositionChanged); |
1411 | |
1412 | QObject::connect(sender: m_graphsItem.get(), |
1413 | signal: &QQuickGraphsItem::ambientLightStrengthChanged, |
1414 | context: q, |
1415 | slot: &Q3DGraphsWidgetItem::ambientLightStrengthChanged); |
1416 | QObject::connect(sender: m_graphsItem.get(), |
1417 | signal: &QQuickGraphsItem::lightStrengthChanged, |
1418 | context: q, |
1419 | slot: &Q3DGraphsWidgetItem::lightStrengthChanged); |
1420 | QObject::connect(sender: m_graphsItem.get(), |
1421 | signal: &QQuickGraphsItem::shadowStrengthChanged, |
1422 | context: q, |
1423 | slot: &Q3DGraphsWidgetItem::shadowStrengthChanged); |
1424 | QObject::connect(sender: m_graphsItem.get(), |
1425 | signal: &QQuickGraphsItem::lightColorChanged, |
1426 | context: q, |
1427 | slot: &Q3DGraphsWidgetItem::lightColorChanged); |
1428 | QObject::connect(sender: m_graphsItem.get(), |
1429 | signal: &QQuickGraphsItem::gridLineTypeChanged, |
1430 | context: q, |
1431 | slot: &Q3DGraphsWidgetItem::gridLineTypeChanged); |
1432 | |
1433 | QObject::connect(sender: m_graphsItem.get(), |
1434 | signal: &QQuickGraphsItem::activeThemeChanged, |
1435 | context: q, |
1436 | slot: &Q3DGraphsWidgetItem::activeThemeChanged); |
1437 | QObject::connect(sender: m_graphsItem.get(), |
1438 | signal: &QQuickGraphsItem::selectionModeChanged, |
1439 | context: q, |
1440 | slot: &Q3DGraphsWidgetItem::selectionModeChanged); |
1441 | QObject::connect(sender: m_graphsItem.get(), |
1442 | signal: &QQuickGraphsItem::shadowQualityChanged, |
1443 | context: q, |
1444 | slot: &Q3DGraphsWidgetItem::shadowQualityChanged); |
1445 | QObject::connect(sender: m_graphsItem.get(), |
1446 | signal: &QQuickGraphsItem::cameraPresetChanged, |
1447 | context: q, |
1448 | slot: &Q3DGraphsWidgetItem::cameraPresetChanged); |
1449 | QObject::connect(sender: m_graphsItem.get(), |
1450 | signal: &QQuickGraphsItem::cameraXRotationChanged, |
1451 | context: q, |
1452 | slot: &Q3DGraphsWidgetItem::cameraXRotationChanged); |
1453 | QObject::connect(sender: m_graphsItem.get(), |
1454 | signal: &QQuickGraphsItem::cameraYRotationChanged, |
1455 | context: q, |
1456 | slot: &Q3DGraphsWidgetItem::cameraYRotationChanged); |
1457 | QObject::connect(sender: m_graphsItem.get(), |
1458 | signal: &QQuickGraphsItem::minCameraXRotationChanged, |
1459 | context: q, |
1460 | slot: &Q3DGraphsWidgetItem::minCameraXRotationChanged); |
1461 | QObject::connect(sender: m_graphsItem.get(), |
1462 | signal: &QQuickGraphsItem::maxCameraXRotationChanged, |
1463 | context: q, |
1464 | slot: &Q3DGraphsWidgetItem::maxCameraXRotationChanged); |
1465 | QObject::connect(sender: m_graphsItem.get(), |
1466 | signal: &QQuickGraphsItem::minCameraYRotationChanged, |
1467 | context: q, |
1468 | slot: &Q3DGraphsWidgetItem::minCameraYRotationChanged); |
1469 | QObject::connect(sender: m_graphsItem.get(), |
1470 | signal: &QQuickGraphsItem::maxCameraYRotationChanged, |
1471 | context: q, |
1472 | slot: &Q3DGraphsWidgetItem::maxCameraYRotationChanged); |
1473 | QObject::connect(sender: m_graphsItem.get(), |
1474 | signal: &QQuickGraphsItem::cameraZoomLevelChanged, |
1475 | context: q, |
1476 | slot: &Q3DGraphsWidgetItem::cameraZoomLevelChanged); |
1477 | QObject::connect(sender: m_graphsItem.get(), |
1478 | signal: &QQuickGraphsItem::minCameraZoomLevelChanged, |
1479 | context: q, |
1480 | slot: &Q3DGraphsWidgetItem::minCameraZoomLevelChanged); |
1481 | QObject::connect(sender: m_graphsItem.get(), |
1482 | signal: &QQuickGraphsItem::maxCameraZoomLevelChanged, |
1483 | context: q, |
1484 | slot: &Q3DGraphsWidgetItem::maxCameraZoomLevelChanged); |
1485 | QObject::connect(sender: m_graphsItem.get(), |
1486 | signal: &QQuickGraphsItem::wrapCameraXRotationChanged, |
1487 | context: q, |
1488 | slot: &Q3DGraphsWidgetItem::wrapCameraXRotationChanged); |
1489 | QObject::connect(sender: m_graphsItem.get(), |
1490 | signal: &QQuickGraphsItem::wrapCameraYRotationChanged, |
1491 | context: q, |
1492 | slot: &Q3DGraphsWidgetItem::wrapCameraYRotationChanged); |
1493 | QObject::connect(sender: m_graphsItem.get(), |
1494 | signal: &QQuickGraphsItem::measureFpsChanged, |
1495 | context: q, |
1496 | slot: &Q3DGraphsWidgetItem::measureFpsChanged); |
1497 | QObject::connect(sender: m_graphsItem.get(), |
1498 | signal: &QQuickGraphsItem::orthoProjectionChanged, |
1499 | context: q, |
1500 | slot: &Q3DGraphsWidgetItem::orthoProjectionChanged); |
1501 | QObject::connect(sender: m_graphsItem.get(), |
1502 | signal: &QQuickGraphsItem::aspectRatioChanged, |
1503 | context: q, |
1504 | slot: &Q3DGraphsWidgetItem::aspectRatioChanged); |
1505 | QObject::connect(sender: m_graphsItem.get(), |
1506 | signal: &QQuickGraphsItem::optimizationHintChanged, |
1507 | context: q, |
1508 | slot: &Q3DGraphsWidgetItem::optimizationHintChanged); |
1509 | QObject::connect(sender: m_graphsItem.get(), |
1510 | signal: &QQuickGraphsItem::polarChanged, |
1511 | context: q, |
1512 | slot: &Q3DGraphsWidgetItem::polarChanged); |
1513 | QObject::connect(sender: m_graphsItem.get(), |
1514 | signal: &QQuickGraphsItem::labelMarginChanged, |
1515 | context: q, |
1516 | slot: &Q3DGraphsWidgetItem::labelMarginChanged); |
1517 | QObject::connect(sender: m_graphsItem.get(), |
1518 | signal: &QQuickGraphsItem::radialLabelOffsetChanged, |
1519 | context: q, |
1520 | slot: &Q3DGraphsWidgetItem::radialLabelOffsetChanged); |
1521 | QObject::connect(sender: m_graphsItem.get(), |
1522 | signal: &QQuickGraphsItem::horizontalAspectRatioChanged, |
1523 | context: q, |
1524 | slot: &Q3DGraphsWidgetItem::horizontalAspectRatioChanged); |
1525 | QObject::connect(sender: m_graphsItem.get(), |
1526 | signal: &QQuickGraphsItem::localeChanged, |
1527 | context: q, |
1528 | slot: &Q3DGraphsWidgetItem::localeChanged); |
1529 | QObject::connect(sender: m_graphsItem.get(), |
1530 | signal: &QQuickGraphsItem::marginChanged, |
1531 | context: q, |
1532 | slot: &Q3DGraphsWidgetItem::marginChanged); |
1533 | |
1534 | m_widget->installEventFilter(filterObj: q); |
1535 | } |
1536 | |
1537 | QT_END_NAMESPACE |
1538 | |