| 1 | /**************************************************************************** | 
| 2 | ** | 
| 3 | ** Copyright (C) 2016 The Qt Company Ltd. | 
| 4 | ** Contact: https://www.qt.io/licensing/ | 
| 5 | ** | 
| 6 | ** This file is part of the Qt Data Visualization module of the Qt Toolkit. | 
| 7 | ** | 
| 8 | ** $QT_BEGIN_LICENSE:GPL$ | 
| 9 | ** Commercial License Usage | 
| 10 | ** Licensees holding valid commercial Qt licenses may use this file in | 
| 11 | ** accordance with the commercial license agreement provided with the | 
| 12 | ** Software or, alternatively, in accordance with the terms contained in | 
| 13 | ** a written agreement between you and The Qt Company. For licensing terms | 
| 14 | ** and conditions see https://www.qt.io/terms-conditions. For further | 
| 15 | ** information use the contact form at https://www.qt.io/contact-us. | 
| 16 | ** | 
| 17 | ** GNU General Public License Usage | 
| 18 | ** Alternatively, this file may be used under the terms of the GNU | 
| 19 | ** General Public License version 3 or (at your option) any later version | 
| 20 | ** approved by the KDE Free Qt Foundation. The licenses are as published by | 
| 21 | ** the Free Software Foundation and appearing in the file LICENSE.GPL3 | 
| 22 | ** included in the packaging of this file. Please review the following | 
| 23 | ** information to ensure the GNU General Public License requirements will | 
| 24 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. | 
| 25 | ** | 
| 26 | ** $QT_END_LICENSE$ | 
| 27 | ** | 
| 28 | ****************************************************************************/ | 
| 29 |  | 
| 30 | #include "qsurface3dseries_p.h" | 
| 31 | #include "surface3dcontroller_p.h" | 
| 32 |  | 
| 33 | QT_BEGIN_NAMESPACE_DATAVISUALIZATION | 
| 34 |  | 
| 35 | /*! | 
| 36 |  * \class QSurface3DSeries | 
| 37 |  * \inmodule QtDataVisualization | 
| 38 |  * \brief The QSurface3DSeries class represents a data series in a 3D surface | 
| 39 |  * graph. | 
| 40 |  * \since QtDataVisualization 1.0 | 
| 41 |  * | 
| 42 |  * This class manages the series specific visual elements, as well as the series | 
| 43 |  * data (via a data proxy). | 
| 44 |  * | 
| 45 |  * If no data proxy is set explicitly for the series, the series creates a default | 
| 46 |  * proxy. Setting another proxy will destroy the existing proxy and all data added to it. | 
| 47 |  * | 
| 48 |  * The object mesh set via the QAbstract3DSeries::mesh property defines the selection | 
| 49 |  * pointer shape in a surface series. | 
| 50 |  * | 
| 51 |  * QSurface3DSeries supports the following format tags for QAbstract3DSeries::setItemLabelFormat(): | 
| 52 |  * \table | 
| 53 |  *   \row | 
| 54 |  *     \li @xTitle    \li Title from x-axis | 
| 55 |  *   \row | 
| 56 |  *     \li @yTitle    \li Title from y-axis | 
| 57 |  *   \row | 
| 58 |  *     \li @zTitle    \li Title from z-axis | 
| 59 |  *   \row | 
| 60 |  *     \li @xLabel    \li Item value formatted using the format of the x-axis. | 
| 61 |  *                        For more information, see | 
| 62 |  *                        \l{QValue3DAxis::setLabelFormat()}. | 
| 63 |  *   \row | 
| 64 |  *     \li @yLabel    \li Item value formatted using the format of the y-axis. | 
| 65 |  *                        For more information, see | 
| 66 |  *                        \l{QValue3DAxis::setLabelFormat()}. | 
| 67 |  *   \row | 
| 68 |  *     \li @zLabel    \li Item value formatted using the format of the z-axis. | 
| 69 |  *                        For more information, see | 
| 70 |  *                        \l{QValue3DAxis::setLabelFormat()}. | 
| 71 |  *   \row | 
| 72 |  *     \li @seriesName \li Name of the series | 
| 73 |  * \endtable | 
| 74 |  * | 
| 75 |  * For example: | 
| 76 |  * \snippet doc_src_qtdatavisualization.cpp 1 | 
| 77 |  * | 
| 78 |  * \sa {Qt Data Visualization Data Handling} | 
| 79 |  */ | 
| 80 |  | 
| 81 | /*! | 
| 82 |  * \qmltype Surface3DSeries | 
| 83 |  * \inqmlmodule QtDataVisualization | 
| 84 |  * \since QtDataVisualization 1.0 | 
| 85 |  * \ingroup datavisualization_qml | 
| 86 |  * \instantiates QSurface3DSeries | 
| 87 |  * \inherits Abstract3DSeries | 
| 88 |  * \brief Represents a data series in a 3D surface graph. | 
| 89 |  * | 
| 90 |  * This type manages the series specific visual elements, as well as the series | 
| 91 |  * data (via a data proxy). | 
| 92 |  * | 
| 93 |  * For a more complete description, see QSurface3DSeries. | 
| 94 |  * | 
| 95 |  * \sa {Qt Data Visualization Data Handling} | 
| 96 |  */ | 
| 97 |  | 
| 98 | /*! | 
| 99 |  * \qmlproperty SurfaceDataProxy Surface3DSeries::dataProxy | 
| 100 |  * | 
| 101 |  * The active data proxy. The series assumes ownership of any proxy set to | 
| 102 |  * it and deletes any previously set proxy when a new one is added. The proxy cannot be null or | 
| 103 |  * set to another series. | 
| 104 |  */ | 
| 105 |  | 
| 106 | /*! | 
| 107 |  * \qmlproperty point Surface3DSeries::selectedPoint | 
| 108 |  * | 
| 109 |  * Sets the surface grid point in the position specified by a row and a column | 
| 110 |  * in the data array of the series as selected. | 
| 111 |  * Only one point can be selected at a time. | 
| 112 |  * | 
| 113 |  * To clear selection from this series, invalidSelectionPosition is set as the position. | 
| 114 |  * If this series is added to a graph, the graph can adjust the selection according to user | 
| 115 |  * interaction or if it becomes invalid. | 
| 116 |  * | 
| 117 |  * Removing rows from or inserting rows to the series before the row of the selected point | 
| 118 |  * will adjust the selection so that the same point will stay selected. | 
| 119 |  * | 
| 120 |  * \sa AbstractGraph3D::clearSelection() | 
| 121 |  */ | 
| 122 |  | 
| 123 | /*! | 
| 124 |  * \qmlproperty point Surface3DSeries::invalidSelectionPosition | 
| 125 |  * A constant property providing an invalid selection position. | 
| 126 |  * This position is set to the selectedPoint property to clear the selection | 
| 127 |  * from this series. | 
| 128 |  * | 
| 129 |  * \sa AbstractGraph3D::clearSelection() | 
| 130 |  */ | 
| 131 |  | 
| 132 | /*! | 
| 133 |  * \qmlproperty bool Surface3DSeries::flatShadingEnabled | 
| 134 |  * | 
| 135 |  * Sets surface flat shading to enabled. It is preset to \c true by default. | 
| 136 |  * When disabled, the normals on the surface are interpolated making the edges look round. | 
| 137 |  * When enabled, the normals are kept the same on a triangle making the color of the triangle solid. | 
| 138 |  * This makes the data more readable from the model. | 
| 139 |  * \note Flat shaded surfaces require at least GLSL version 1.2 with GL_EXT_gpu_shader4 extension. | 
| 140 |  * The value of the flatShadingSupported property indicates whether flat shading | 
| 141 |  * is supported at runtime. | 
| 142 |  */ | 
| 143 |  | 
| 144 | /*! | 
| 145 |  * \qmlproperty bool Surface3DSeries::flatShadingSupported | 
| 146 |  * | 
| 147 |  * Indicates whether flat shading for surfaces is supported by the current system. | 
| 148 |  * It requires at least GLSL version 1.2 with GL_EXT_gpu_shader4 extension. | 
| 149 |  * | 
| 150 |  * \note This read-only property is set to its correct value after the first | 
| 151 |  * render pass. Until then it is always \c true. | 
| 152 |  */ | 
| 153 |  | 
| 154 | /*! | 
| 155 |  * \qmlproperty DrawFlag Surface3DSeries::drawMode | 
| 156 |  * | 
| 157 |  * Sets the drawing mode to one of \l{QSurface3DSeries::DrawFlag}{Surface3DSeries.DrawFlag}. | 
| 158 |  * Clearing all flags is not allowed. | 
| 159 |  */ | 
| 160 |  | 
| 161 | /*! | 
| 162 |  * \qmlproperty string Surface3DSeries::textureFile | 
| 163 |  * | 
| 164 |  * The texture file name for the surface texture. To clear the texture, an empty | 
| 165 |  * file name is set. | 
| 166 |  */ | 
| 167 |  | 
| 168 |  | 
| 169 | /*! | 
| 170 |  * \enum QSurface3DSeries::DrawFlag | 
| 171 |  * | 
| 172 |  * The drawing mode of the surface. Values of this enumeration can be combined | 
| 173 |  * with the OR operator. | 
| 174 |  * | 
| 175 |  * \value DrawWireframe | 
| 176 |  *        Only the grid is drawn. | 
| 177 |  * \value DrawSurface | 
| 178 |  *        Only the surface is drawn. | 
| 179 |  * \value DrawSurfaceAndWireframe | 
| 180 |  *        Both the surface and grid are drawn. | 
| 181 |  */ | 
| 182 |  | 
| 183 | /*! | 
| 184 |  * Constructs a surface 3D series with the parent \a parent. | 
| 185 |  */ | 
| 186 | QSurface3DSeries::QSurface3DSeries(QObject *parent) : | 
| 187 |     QAbstract3DSeries(new QSurface3DSeriesPrivate(this), parent) | 
| 188 | { | 
| 189 |     // Default proxy | 
| 190 |     dptr()->setDataProxy(new QSurfaceDataProxy); | 
| 191 | } | 
| 192 |  | 
| 193 | /*! | 
| 194 |  * Constructs a surface 3D series with the data proxy \a dataProxy and the | 
| 195 |  * parent \a parent. | 
| 196 |  */ | 
| 197 | QSurface3DSeries::QSurface3DSeries(QSurfaceDataProxy *dataProxy, QObject *parent) : | 
| 198 |     QAbstract3DSeries(new QSurface3DSeriesPrivate(this), parent) | 
| 199 | { | 
| 200 |     dptr()->setDataProxy(dataProxy); | 
| 201 | } | 
| 202 |  | 
| 203 | /*! | 
| 204 |  * \internal | 
| 205 |  */ | 
| 206 | QSurface3DSeries::QSurface3DSeries(QSurface3DSeriesPrivate *d, QObject *parent) : | 
| 207 |     QAbstract3DSeries(d, parent) | 
| 208 | { | 
| 209 | } | 
| 210 |  | 
| 211 | /*! | 
| 212 |  * Deletes the surface 3D series. | 
| 213 |  */ | 
| 214 | QSurface3DSeries::~QSurface3DSeries() | 
| 215 | { | 
| 216 | } | 
| 217 |  | 
| 218 | /*! | 
| 219 |  * \property QSurface3DSeries::dataProxy | 
| 220 |  * | 
| 221 |  * \brief The active data proxy. | 
| 222 |  * | 
| 223 |  * The series assumes ownership of any proxy set to it and deletes any | 
| 224 |  * previously set proxy when a new one is added. The proxy cannot be null or | 
| 225 |  * set to another series. | 
| 226 |  */ | 
| 227 | void QSurface3DSeries::setDataProxy(QSurfaceDataProxy *proxy) | 
| 228 | { | 
| 229 |     d_ptr->setDataProxy(proxy); | 
| 230 | } | 
| 231 |  | 
| 232 | QSurfaceDataProxy *QSurface3DSeries::dataProxy() const | 
| 233 | { | 
| 234 |     return static_cast<QSurfaceDataProxy *>(d_ptr->dataProxy()); | 
| 235 | } | 
| 236 |  | 
| 237 | /*! | 
| 238 |  * \property QSurface3DSeries::selectedPoint | 
| 239 |  * | 
| 240 |  * \brief The surface grid point that is selected in the series. | 
| 241 |  */ | 
| 242 |  | 
| 243 | /*! | 
| 244 |  * Selects a surface grid point at the position \a position in the data array of | 
| 245 |  * the series specified by a row and a column. | 
| 246 |  * | 
| 247 |  * Only one point can be selected at a time. | 
| 248 |  * | 
| 249 |  * To clear selection from this series, invalidSelectionPosition() is set as \a position. | 
| 250 |  * If this series is added to a graph, the graph can adjust the selection according to user | 
| 251 |  * interaction or if it becomes invalid. | 
| 252 |  * | 
| 253 |  * Removing rows from or inserting rows to the series before the row of the selected point | 
| 254 |  * will adjust the selection so that the same point will stay selected. | 
| 255 |  * | 
| 256 |  * \sa QAbstract3DGraph::clearSelection() | 
| 257 |  */ | 
| 258 | void QSurface3DSeries::setSelectedPoint(const QPoint &position) | 
| 259 | { | 
| 260 |     // Don't do this in private to avoid loops, as that is used for callback from controller. | 
| 261 |     if (d_ptr->m_controller) | 
| 262 |         static_cast<Surface3DController *>(d_ptr->m_controller)->setSelectedPoint(position, series: this, enterSlice: true); | 
| 263 |     else | 
| 264 |         dptr()->setSelectedPoint(position); | 
| 265 | } | 
| 266 |  | 
| 267 | QPoint QSurface3DSeries::selectedPoint() const | 
| 268 | { | 
| 269 |     return dptrc()->m_selectedPoint; | 
| 270 | } | 
| 271 |  | 
| 272 | /*! | 
| 273 |  * Returns the QPoint signifying an invalid selection position. This is set to | 
| 274 |  * the selectedPoint property to clear the selection from this series. | 
| 275 |  * | 
| 276 |  * \sa QAbstract3DGraph::clearSelection() | 
| 277 |  */ | 
| 278 | QPoint QSurface3DSeries::invalidSelectionPosition() | 
| 279 | { | 
| 280 |     return Surface3DController::invalidSelectionPosition(); | 
| 281 | } | 
| 282 |  | 
| 283 | /*! | 
| 284 |  * \property QSurface3DSeries::flatShadingEnabled | 
| 285 |  * | 
| 286 |  * \brief Whether surface flat shading is enabled. | 
| 287 |  * | 
| 288 |  * Preset to \c true by default. | 
| 289 |  * | 
| 290 |  * When disabled, the normals on the surface are interpolated making the edges look round. | 
| 291 |  * When enabled, the normals are kept the same on a triangle making the color of the triangle solid. | 
| 292 |  * This makes the data more readable from the model. | 
| 293 |  * \note Flat shaded surfaces require at least GLSL version 1.2 with GL_EXT_gpu_shader4 extension. | 
| 294 |  * The value of the flatShadingSupported property indicates whether flat shading | 
| 295 |  * is supported at runtime. | 
| 296 |  */ | 
| 297 | void QSurface3DSeries::setFlatShadingEnabled(bool enabled) | 
| 298 | { | 
| 299 |     if (dptr()->m_flatShadingEnabled != enabled) { | 
| 300 |         dptr()->setFlatShadingEnabled(enabled); | 
| 301 |         emit flatShadingEnabledChanged(enable: enabled); | 
| 302 |     } | 
| 303 | } | 
| 304 |  | 
| 305 | bool QSurface3DSeries::isFlatShadingEnabled() const | 
| 306 | { | 
| 307 |     return dptrc()->m_flatShadingEnabled; | 
| 308 | } | 
| 309 |  | 
| 310 | /*! | 
| 311 |  * \property QSurface3DSeries::flatShadingSupported | 
| 312 |  * | 
| 313 |  * \brief Whether surface flat shading is supported by the current system. | 
| 314 |  * | 
| 315 |  * Flat shading for surfaces requires at least GLSL version 1.2 with GL_EXT_gpu_shader4 extension. | 
| 316 |  * If \c true, flat shading for surfaces is supported. | 
| 317 |  * \note This read-only property is set to its correct value after the first | 
| 318 |  * render pass. Until then it is always \c true. | 
| 319 |  */ | 
| 320 | bool QSurface3DSeries::isFlatShadingSupported() const | 
| 321 | { | 
| 322 |     if (d_ptr->m_controller) | 
| 323 |         return static_cast<Surface3DController *>(d_ptr->m_controller)->isFlatShadingSupported(); | 
| 324 |     else | 
| 325 |         return true; | 
| 326 | } | 
| 327 |  | 
| 328 | /*! | 
| 329 |  * \property QSurface3DSeries::drawMode | 
| 330 |  * | 
| 331 |  * The drawing mode. | 
| 332 |  * | 
| 333 |  * Possible values are the values of DrawFlag. Clearing all flags is not allowed. | 
| 334 |  */ | 
| 335 | void QSurface3DSeries::setDrawMode(DrawFlags mode) | 
| 336 | { | 
| 337 |     if (dptr()->m_drawMode != mode) { | 
| 338 |         dptr()->setDrawMode(mode); | 
| 339 |         emit drawModeChanged(mode); | 
| 340 |     } | 
| 341 | } | 
| 342 |  | 
| 343 | QSurface3DSeries::DrawFlags QSurface3DSeries::drawMode() const | 
| 344 | { | 
| 345 |     return dptrc()->m_drawMode; | 
| 346 | } | 
| 347 |  | 
| 348 | /*! | 
| 349 |  * \property QSurface3DSeries::texture | 
| 350 |  * | 
| 351 |  * \brief The texture for the surface as a QImage. | 
| 352 |  * | 
| 353 |  * Setting an empty QImage clears the texture. | 
| 354 |  */ | 
| 355 | void QSurface3DSeries::setTexture(const QImage &texture) | 
| 356 | { | 
| 357 |     if (dptr()->m_texture != texture) { | 
| 358 |         dptr()->setTexture(texture); | 
| 359 |  | 
| 360 |         emit textureChanged(image: texture); | 
| 361 |         dptr()->m_textureFile.clear(); | 
| 362 |     } | 
| 363 | } | 
| 364 |  | 
| 365 | QImage QSurface3DSeries::texture() const | 
| 366 | { | 
| 367 |     return dptrc()->m_texture; | 
| 368 | } | 
| 369 |  | 
| 370 | /*! | 
| 371 |  * \property QSurface3DSeries::textureFile | 
| 372 |  * | 
| 373 |  * \brief The texture for the surface as a file. | 
| 374 |  * | 
| 375 |  * Setting an empty file name clears the texture. | 
| 376 |  */ | 
| 377 | void QSurface3DSeries::setTextureFile(const QString &filename) | 
| 378 | { | 
| 379 |     if (dptr()->m_textureFile != filename) { | 
| 380 |         if (filename.isEmpty()) { | 
| 381 |             setTexture(QImage()); | 
| 382 |         } else { | 
| 383 |             QImage image(filename); | 
| 384 |             if (image.isNull()) { | 
| 385 |                 qWarning() << "Warning: Tried to set invalid image file as surface texture." ; | 
| 386 |                 return; | 
| 387 |             } | 
| 388 |             setTexture(image); | 
| 389 |         } | 
| 390 |  | 
| 391 |         dptr()->m_textureFile = filename; | 
| 392 |         emit textureFileChanged(filename); | 
| 393 |     } | 
| 394 | } | 
| 395 |  | 
| 396 | QString QSurface3DSeries::textureFile() const | 
| 397 | { | 
| 398 |     return dptrc()->m_textureFile; | 
| 399 | } | 
| 400 |  | 
| 401 | /*! | 
| 402 |  * \internal | 
| 403 |  */ | 
| 404 | QSurface3DSeriesPrivate *QSurface3DSeries::dptr() | 
| 405 | { | 
| 406 |     return static_cast<QSurface3DSeriesPrivate *>(d_ptr.data()); | 
| 407 | } | 
| 408 |  | 
| 409 | /*! | 
| 410 |  * \internal | 
| 411 |  */ | 
| 412 | const QSurface3DSeriesPrivate *QSurface3DSeries::dptrc() const | 
| 413 | { | 
| 414 |     return static_cast<const QSurface3DSeriesPrivate *>(d_ptr.data()); | 
| 415 | } | 
| 416 |  | 
| 417 | // QSurface3DSeriesPrivate | 
| 418 |  | 
| 419 | QSurface3DSeriesPrivate::QSurface3DSeriesPrivate(QSurface3DSeries *q) | 
| 420 |     : QAbstract3DSeriesPrivate(q, QAbstract3DSeries::SeriesTypeSurface), | 
| 421 |       m_selectedPoint(Surface3DController::invalidSelectionPosition()), | 
| 422 |       m_flatShadingEnabled(true), | 
| 423 |       m_drawMode(QSurface3DSeries::DrawSurfaceAndWireframe) | 
| 424 | { | 
| 425 |     m_itemLabelFormat = QStringLiteral("@xLabel, @yLabel, @zLabel" ); | 
| 426 |     m_mesh = QAbstract3DSeries::MeshSphere; | 
| 427 | } | 
| 428 |  | 
| 429 | QSurface3DSeriesPrivate::~QSurface3DSeriesPrivate() | 
| 430 | { | 
| 431 | } | 
| 432 |  | 
| 433 | QSurface3DSeries *QSurface3DSeriesPrivate::qptr() | 
| 434 | { | 
| 435 |     return static_cast<QSurface3DSeries *>(q_ptr); | 
| 436 | } | 
| 437 |  | 
| 438 | void QSurface3DSeriesPrivate::setDataProxy(QAbstractDataProxy *proxy) | 
| 439 | { | 
| 440 |     Q_ASSERT(proxy->type() == QAbstractDataProxy::DataTypeSurface); | 
| 441 |  | 
| 442 |     QAbstract3DSeriesPrivate::setDataProxy(proxy); | 
| 443 |  | 
| 444 |     emit qptr()->dataProxyChanged(proxy: static_cast<QSurfaceDataProxy *>(proxy)); | 
| 445 | } | 
| 446 |  | 
| 447 | void QSurface3DSeriesPrivate::connectControllerAndProxy(Abstract3DController *newController) | 
| 448 | { | 
| 449 |     QSurfaceDataProxy *surfaceDataProxy = static_cast<QSurfaceDataProxy *>(m_dataProxy); | 
| 450 |  | 
| 451 |     if (m_controller && surfaceDataProxy) { | 
| 452 |         //Disconnect old controller/old proxy | 
| 453 |         QObject::disconnect(sender: surfaceDataProxy, signal: 0, receiver: m_controller, member: 0); | 
| 454 |         QObject::disconnect(sender: q_ptr, signal: 0, receiver: m_controller, member: 0); | 
| 455 |     } | 
| 456 |  | 
| 457 |     if (newController && surfaceDataProxy) { | 
| 458 |         Surface3DController *controller = static_cast<Surface3DController *>(newController); | 
| 459 |  | 
| 460 |         QObject::connect(sender: surfaceDataProxy, signal: &QSurfaceDataProxy::arrayReset, receiver: controller, | 
| 461 |                          slot: &Surface3DController::handleArrayReset); | 
| 462 |         QObject::connect(sender: surfaceDataProxy, signal: &QSurfaceDataProxy::rowsAdded, receiver: controller, | 
| 463 |                          slot: &Surface3DController::handleRowsAdded); | 
| 464 |         QObject::connect(sender: surfaceDataProxy, signal: &QSurfaceDataProxy::rowsChanged, receiver: controller, | 
| 465 |                          slot: &Surface3DController::handleRowsChanged); | 
| 466 |         QObject::connect(sender: surfaceDataProxy, signal: &QSurfaceDataProxy::rowsRemoved, receiver: controller, | 
| 467 |                          slot: &Surface3DController::handleRowsRemoved); | 
| 468 |         QObject::connect(sender: surfaceDataProxy, signal: &QSurfaceDataProxy::rowsInserted, receiver: controller, | 
| 469 |                          slot: &Surface3DController::handleRowsInserted); | 
| 470 |         QObject::connect(sender: surfaceDataProxy, signal: &QSurfaceDataProxy::itemChanged, receiver: controller, | 
| 471 |                          slot: &Surface3DController::handleItemChanged); | 
| 472 |         QObject::connect(sender: qptr(), signal: &QSurface3DSeries::dataProxyChanged, receiver: controller, | 
| 473 |                          slot: &Surface3DController::handleArrayReset); | 
| 474 |     } | 
| 475 | } | 
| 476 |  | 
| 477 | void QSurface3DSeriesPrivate::createItemLabel() | 
| 478 | { | 
| 479 |     static const QString xTitleTag(QStringLiteral("@xTitle" )); | 
| 480 |     static const QString yTitleTag(QStringLiteral("@yTitle" )); | 
| 481 |     static const QString zTitleTag(QStringLiteral("@zTitle" )); | 
| 482 |     static const QString xLabelTag(QStringLiteral("@xLabel" )); | 
| 483 |     static const QString yLabelTag(QStringLiteral("@yLabel" )); | 
| 484 |     static const QString zLabelTag(QStringLiteral("@zLabel" )); | 
| 485 |     static const QString seriesNameTag(QStringLiteral("@seriesName" )); | 
| 486 |  | 
| 487 |     if (m_selectedPoint == QSurface3DSeries::invalidSelectionPosition()) { | 
| 488 |         m_itemLabel = QString(); | 
| 489 |         return; | 
| 490 |     } | 
| 491 |  | 
| 492 |     QValue3DAxis *axisX = static_cast<QValue3DAxis *>(m_controller->axisX()); | 
| 493 |     QValue3DAxis *axisY = static_cast<QValue3DAxis *>(m_controller->axisY()); | 
| 494 |     QValue3DAxis *axisZ = static_cast<QValue3DAxis *>(m_controller->axisZ()); | 
| 495 |     QVector3D selectedPosition = qptr()->dataProxy()->itemAt(position: m_selectedPoint)->position(); | 
| 496 |  | 
| 497 |     m_itemLabel = m_itemLabelFormat; | 
| 498 |  | 
| 499 |     m_itemLabel.replace(before: xTitleTag, after: axisX->title()); | 
| 500 |     m_itemLabel.replace(before: yTitleTag, after: axisY->title()); | 
| 501 |     m_itemLabel.replace(before: zTitleTag, after: axisZ->title()); | 
| 502 |  | 
| 503 |     if (m_itemLabel.contains(s: xLabelTag)) { | 
| 504 |         QString valueLabelText = axisX->formatter()->stringForValue( | 
| 505 |                     value: qreal(selectedPosition.x()), format: axisX->labelFormat()); | 
| 506 |         m_itemLabel.replace(before: xLabelTag, after: valueLabelText); | 
| 507 |     } | 
| 508 |     if (m_itemLabel.contains(s: yLabelTag)) { | 
| 509 |         QString valueLabelText = axisY->formatter()->stringForValue( | 
| 510 |                     value: qreal(selectedPosition.y()), format: axisY->labelFormat()); | 
| 511 |         m_itemLabel.replace(before: yLabelTag, after: valueLabelText); | 
| 512 |     } | 
| 513 |     if (m_itemLabel.contains(s: zLabelTag)) { | 
| 514 |         QString valueLabelText = axisZ->formatter()->stringForValue( | 
| 515 |                     value: qreal(selectedPosition.z()), format: axisZ->labelFormat()); | 
| 516 |         m_itemLabel.replace(before: zLabelTag, after: valueLabelText); | 
| 517 |     } | 
| 518 |     m_itemLabel.replace(before: seriesNameTag, after: m_name); | 
| 519 | } | 
| 520 |  | 
| 521 | void QSurface3DSeriesPrivate::setSelectedPoint(const QPoint &position) | 
| 522 | { | 
| 523 |     if (position != m_selectedPoint) { | 
| 524 |         markItemLabelDirty(); | 
| 525 |         m_selectedPoint = position; | 
| 526 |         emit qptr()->selectedPointChanged(position: m_selectedPoint); | 
| 527 |     } | 
| 528 | } | 
| 529 |  | 
| 530 | void QSurface3DSeriesPrivate::setFlatShadingEnabled(bool enabled) | 
| 531 | { | 
| 532 |     m_flatShadingEnabled = enabled; | 
| 533 |     if (m_controller) | 
| 534 |         m_controller->markSeriesVisualsDirty(); | 
| 535 | } | 
| 536 |  | 
| 537 | void QSurface3DSeriesPrivate::setDrawMode(QSurface3DSeries::DrawFlags mode) | 
| 538 | { | 
| 539 |     if (mode.testFlag(flag: QSurface3DSeries::DrawWireframe) | 
| 540 |             || mode.testFlag(flag: QSurface3DSeries::DrawSurface)) { | 
| 541 |         m_drawMode = mode; | 
| 542 |         if (m_controller) | 
| 543 |             m_controller->markSeriesVisualsDirty(); | 
| 544 |     } else { | 
| 545 |         qWarning(msg: "You may not clear all draw flags. Mode not changed." ); | 
| 546 |     } | 
| 547 | } | 
| 548 |  | 
| 549 | void QSurface3DSeriesPrivate::setTexture(const QImage &texture) | 
| 550 | { | 
| 551 |     m_texture = texture; | 
| 552 |     if (static_cast<Surface3DController *>(m_controller)) | 
| 553 |         static_cast<Surface3DController *>(m_controller)->updateSurfaceTexture(series: qptr()); | 
| 554 | } | 
| 555 |  | 
| 556 | QT_END_NAMESPACE_DATAVISUALIZATION | 
| 557 |  |