1 | // Copyright (C) 2023 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only |
3 | |
4 | // |
5 | // W A R N I N G |
6 | // ------------- |
7 | // |
8 | // This file is not part of the QtGraphs API. It exists purely as an |
9 | // implementation detail. This header file may change from version to |
10 | // version without notice, or even be removed. |
11 | // |
12 | // We mean it. |
13 | |
14 | #ifndef ABSTRACT3DCONTROLLER_P_H |
15 | #define ABSTRACT3DCONTROLLER_P_H |
16 | |
17 | #include <private/graphsglobal_p.h> |
18 | |
19 | #include "qabstract3daxis.h" |
20 | #include "qabstract3dinputhandler.h" |
21 | #include "qabstract3dgraph.h" |
22 | #include "qcustom3ditem.h" |
23 | #include <QtGui/QLinearGradient> |
24 | #include <QtCore/QElapsedTimer> |
25 | #include <QtCore/QLocale> |
26 | #include <QtCore/QMutex> |
27 | |
28 | QT_FORWARD_DECLARE_CLASS(QOpenGLFramebufferObject) |
29 | |
30 | QT_BEGIN_NAMESPACE |
31 | |
32 | class QValue3DAxis; |
33 | class QCategory3DAxis; |
34 | class AbstractDeclarative; |
35 | class QAbstract3DSeries; |
36 | class ThemeManager; |
37 | |
38 | struct Abstract3DChangeBitField { |
39 | bool themeChanged : 1; |
40 | bool shadowQualityChanged : 1; |
41 | bool selectionModeChanged : 1; |
42 | bool optimizationHintChanged : 1; |
43 | bool axisXTypeChanged : 1; |
44 | bool axisYTypeChanged : 1; |
45 | bool axisZTypeChanged : 1; |
46 | bool axisXTitleChanged : 1; |
47 | bool axisYTitleChanged : 1; |
48 | bool axisZTitleChanged : 1; |
49 | bool axisXLabelsChanged : 1; |
50 | bool axisYLabelsChanged : 1; |
51 | bool axisZLabelsChanged : 1; |
52 | bool axisXRangeChanged : 1; |
53 | bool axisYRangeChanged : 1; |
54 | bool axisZRangeChanged : 1; |
55 | bool axisXSegmentCountChanged : 1; |
56 | bool axisYSegmentCountChanged : 1; |
57 | bool axisZSegmentCountChanged : 1; |
58 | bool axisXSubSegmentCountChanged : 1; |
59 | bool axisYSubSegmentCountChanged : 1; |
60 | bool axisZSubSegmentCountChanged : 1; |
61 | bool axisXLabelFormatChanged : 1; |
62 | bool axisYLabelFormatChanged : 1; |
63 | bool axisZLabelFormatChanged : 1; |
64 | bool axisXReversedChanged : 1; |
65 | bool axisYReversedChanged : 1; |
66 | bool axisZReversedChanged : 1; |
67 | bool axisXFormatterChanged : 1; |
68 | bool axisYFormatterChanged : 1; |
69 | bool axisZFormatterChanged : 1; |
70 | bool projectionChanged : 1; |
71 | bool axisXLabelAutoRotationChanged : 1; |
72 | bool axisYLabelAutoRotationChanged : 1; |
73 | bool axisZLabelAutoRotationChanged : 1; |
74 | bool aspectRatioChanged : 1; |
75 | bool horizontalAspectRatioChanged : 1; |
76 | bool axisXTitleVisibilityChanged : 1; |
77 | bool axisYTitleVisibilityChanged : 1; |
78 | bool axisZTitleVisibilityChanged : 1; |
79 | bool axisXTitleFixedChanged : 1; |
80 | bool axisYTitleFixedChanged : 1; |
81 | bool axisZTitleFixedChanged : 1; |
82 | bool polarChanged : 1; |
83 | bool radialLabelOffsetChanged : 1; |
84 | bool reflectionChanged : 1; |
85 | bool reflectivityChanged : 1; |
86 | bool marginChanged : 1; |
87 | |
88 | Abstract3DChangeBitField() : |
89 | themeChanged(true), |
90 | shadowQualityChanged(true), |
91 | selectionModeChanged(true), |
92 | optimizationHintChanged(true), |
93 | axisXTypeChanged(true), |
94 | axisYTypeChanged(true), |
95 | axisZTypeChanged(true), |
96 | axisXTitleChanged(true), |
97 | axisYTitleChanged(true), |
98 | axisZTitleChanged(true), |
99 | axisXLabelsChanged(true), |
100 | axisYLabelsChanged(true), |
101 | axisZLabelsChanged(true), |
102 | axisXRangeChanged(true), |
103 | axisYRangeChanged(true), |
104 | axisZRangeChanged(true), |
105 | axisXSegmentCountChanged(true), |
106 | axisYSegmentCountChanged(true), |
107 | axisZSegmentCountChanged(true), |
108 | axisXSubSegmentCountChanged(true), |
109 | axisYSubSegmentCountChanged(true), |
110 | axisZSubSegmentCountChanged(true), |
111 | axisXLabelFormatChanged(true), |
112 | axisYLabelFormatChanged(true), |
113 | axisZLabelFormatChanged(true), |
114 | axisXReversedChanged(true), |
115 | axisYReversedChanged(true), |
116 | axisZReversedChanged(true), |
117 | axisXFormatterChanged(true), |
118 | axisYFormatterChanged(true), |
119 | axisZFormatterChanged(true), |
120 | projectionChanged(true), |
121 | axisXLabelAutoRotationChanged(true), |
122 | axisYLabelAutoRotationChanged(true), |
123 | axisZLabelAutoRotationChanged(true), |
124 | aspectRatioChanged(true), |
125 | horizontalAspectRatioChanged(true), |
126 | axisXTitleVisibilityChanged(true), |
127 | axisYTitleVisibilityChanged(true), |
128 | axisZTitleVisibilityChanged(true), |
129 | axisXTitleFixedChanged(true), |
130 | axisYTitleFixedChanged(true), |
131 | axisZTitleFixedChanged(true), |
132 | polarChanged(true), |
133 | radialLabelOffsetChanged(true), |
134 | reflectionChanged(true), |
135 | reflectivityChanged(true), |
136 | marginChanged(true) |
137 | { |
138 | } |
139 | }; |
140 | |
141 | class Q_GRAPHS_EXPORT Abstract3DController : public QObject |
142 | { |
143 | Q_OBJECT |
144 | |
145 | public: |
146 | enum SelectionType { |
147 | SelectionNone = 0, |
148 | SelectionItem, |
149 | SelectionRow, |
150 | SelectionColumn |
151 | }; |
152 | |
153 | private: |
154 | Abstract3DChangeBitField m_changeTracker; |
155 | ThemeManager *m_themeManager; |
156 | QAbstract3DGraph::SelectionFlags m_selectionMode; |
157 | QAbstract3DGraph::ShadowQuality m_shadowQuality; |
158 | bool m_useOrthoProjection; |
159 | qreal m_aspectRatio; |
160 | qreal m_horizontalAspectRatio; |
161 | QAbstract3DGraph::OptimizationHints m_optimizationHints; |
162 | bool m_reflectionEnabled; |
163 | qreal m_reflectivity; |
164 | QLocale m_locale; |
165 | QVector3D m_queriedGraphPosition; |
166 | bool m_graphPositionQueryPending = false; |
167 | |
168 | protected: |
169 | Q3DScene *m_scene; |
170 | // Active axes |
171 | QAbstract3DAxis *m_axisX; |
172 | QAbstract3DAxis *m_axisY; |
173 | QAbstract3DAxis *m_axisZ; |
174 | |
175 | QList<QAbstract3DAxis *> m_axes; // List of all added axes |
176 | bool m_isDataDirty; |
177 | bool m_isCustomDataDirty; |
178 | bool m_isCustomItemDirty; |
179 | bool m_isSeriesVisualsDirty; |
180 | bool m_renderPending; |
181 | bool m_isPolar; |
182 | float m_radialLabelOffset; |
183 | |
184 | QList<QAbstract3DSeries *> m_seriesList; |
185 | |
186 | QList<QAbstract3DSeries *> m_changedSeriesList; |
187 | |
188 | QList<QCustom3DItem *> m_customItems; |
189 | |
190 | QAbstract3DGraph::ElementType m_clickedType; |
191 | int m_selectedLabelIndex; |
192 | int m_selectedCustomItemIndex; |
193 | qreal m_margin; |
194 | |
195 | QMutex m_renderMutex; |
196 | QQuickGraphsItem *m_qml = nullptr; |
197 | |
198 | explicit Abstract3DController(QRect initialViewport, Q3DScene *scene, QObject *parent = 0); |
199 | |
200 | public: |
201 | virtual ~Abstract3DController(); |
202 | |
203 | virtual void addSeries(QAbstract3DSeries *series); |
204 | virtual void insertSeries(int index, QAbstract3DSeries *series); |
205 | virtual void removeSeries(QAbstract3DSeries *series); |
206 | virtual bool hasSeries(QAbstract3DSeries *series); |
207 | QList<QAbstract3DSeries *> seriesList(); |
208 | |
209 | virtual void setAxisX(QAbstract3DAxis *axis); |
210 | virtual QAbstract3DAxis *axisX() const; |
211 | virtual void setAxisY(QAbstract3DAxis *axis); |
212 | virtual QAbstract3DAxis *axisY() const; |
213 | virtual void setAxisZ(QAbstract3DAxis *axis); |
214 | virtual QAbstract3DAxis *axisZ() const; |
215 | virtual void addAxis(QAbstract3DAxis *axis); |
216 | virtual void releaseAxis(QAbstract3DAxis *axis); |
217 | virtual QList<QAbstract3DAxis *> axes() const; // Omits default axes |
218 | |
219 | virtual void addTheme(Q3DTheme *theme); |
220 | virtual void releaseTheme(Q3DTheme *theme); |
221 | virtual void setActiveTheme(Q3DTheme *theme, bool force = true); |
222 | virtual Q3DTheme *activeTheme() const; |
223 | virtual QList<Q3DTheme *> themes() const; |
224 | |
225 | virtual void setSelectionMode(QAbstract3DGraph::SelectionFlags mode); |
226 | virtual QAbstract3DGraph::SelectionFlags selectionMode() const; |
227 | |
228 | virtual void setShadowQuality(QAbstract3DGraph::ShadowQuality quality); |
229 | virtual void doSetShadowQuality(QAbstract3DGraph::ShadowQuality quality); |
230 | virtual QAbstract3DGraph::ShadowQuality shadowQuality() const; |
231 | |
232 | void setOptimizationHints(QAbstract3DGraph::OptimizationHints hints); |
233 | QAbstract3DGraph::OptimizationHints optimizationHints() const; |
234 | |
235 | bool isSlicingActive() const; |
236 | void setSlicingActive(bool isSlicing); |
237 | |
238 | bool isCustomDataDirty() const { return m_isCustomDataDirty; } |
239 | void setCustomDataDirty(bool dirty) { m_isCustomDataDirty = dirty; } |
240 | bool isCustomItemDirty() const { return m_isCustomItemDirty; } |
241 | void setCustomItemDirty(bool dirty) { m_isCustomItemDirty = dirty; } |
242 | bool isCustomLabelItem(QCustom3DItem *item) const; |
243 | bool isCustomVolumeItem(QCustom3DItem *item) const; |
244 | QImage customTextureImage(QCustom3DItem *item); |
245 | Q3DScene *scene(); |
246 | |
247 | void markDataDirty(); |
248 | void markSeriesVisualsDirty(); |
249 | |
250 | void requestRender(QOpenGLFramebufferObject *fbo); |
251 | |
252 | int addCustomItem(QCustom3DItem *item); |
253 | void deleteCustomItems(); |
254 | void deleteCustomItem(QCustom3DItem *item); |
255 | void deleteCustomItem(const QVector3D &position); |
256 | void releaseCustomItem(QCustom3DItem *item); |
257 | QList<QCustom3DItem *> customItems() const; |
258 | |
259 | int selectedLabelIndex() const; |
260 | QAbstract3DAxis *selectedAxis() const; |
261 | int selectedCustomItemIndex() const; |
262 | QCustom3DItem *selectedCustomItem() const; |
263 | |
264 | void setOrthoProjection(bool enable); |
265 | bool isOrthoProjection() const; |
266 | |
267 | QAbstract3DGraph::ElementType selectedElement() const; |
268 | |
269 | void setAspectRatio(qreal ratio); |
270 | qreal aspectRatio(); |
271 | void setHorizontalAspectRatio(qreal ratio); |
272 | qreal horizontalAspectRatio() const; |
273 | |
274 | void setReflection(bool enable); |
275 | bool reflection() const; |
276 | void setReflectivity(qreal reflectivity); |
277 | qreal reflectivity() const; |
278 | |
279 | void setPolar(bool enable); |
280 | bool isPolar() const; |
281 | void setRadialLabelOffset(float offset); |
282 | float radialLabelOffset() const; |
283 | |
284 | void setLocale(const QLocale &locale); |
285 | QLocale locale() const; |
286 | |
287 | QVector3D queriedGraphPosition() const; |
288 | void setQueriedGraphPosition(const QVector3D &position) { m_queriedGraphPosition = position; } |
289 | |
290 | void setMargin(qreal margin); |
291 | qreal margin() const; |
292 | |
293 | void emitNeedRender(); |
294 | |
295 | virtual void clearSelection() = 0; |
296 | |
297 | virtual void handleAxisTitleChangedBySender(QObject *sender); |
298 | virtual void handleAxisLabelsChangedBySender(QObject *sender); |
299 | virtual void handleAxisRangeChangedBySender(QObject *sender); |
300 | virtual void handleAxisSegmentCountChangedBySender(QObject *sender); |
301 | virtual void handleAxisSubSegmentCountChangedBySender(QObject *sender); |
302 | virtual void handleAxisAutoAdjustRangeChangedInOrientation( |
303 | QAbstract3DAxis::AxisOrientation orientation, bool autoAdjust) = 0; |
304 | virtual void handleAxisLabelFormatChangedBySender(QObject *sender); |
305 | virtual void handleAxisReversedChangedBySender(QObject *sender); |
306 | virtual void handleAxisFormatterDirtyBySender(QObject *sender); |
307 | virtual void handleAxisLabelAutoRotationChangedBySender(QObject *sender); |
308 | virtual void handleAxisTitleVisibilityChangedBySender(QObject *sender); |
309 | virtual void handleAxisTitleFixedChangedBySender(QObject *sender); |
310 | virtual void handleSeriesVisibilityChangedBySender(QObject *sender); |
311 | virtual void adjustAxisRanges() = 0; |
312 | |
313 | void markSeriesItemLabelsDirty(); |
314 | |
315 | bool graphPositionQueryPending() const { return m_graphPositionQueryPending; } |
316 | void setGraphPositionQueryPending(const bool &pending) { m_graphPositionQueryPending = pending; } |
317 | |
318 | public Q_SLOTS: |
319 | void handleAxisTitleChanged(const QString &title); |
320 | void handleAxisLabelsChanged(); |
321 | void handleAxisRangeChanged(float min, float max); |
322 | void handleAxisSegmentCountChanged(int count); |
323 | void handleAxisSubSegmentCountChanged(int count); |
324 | void handleAxisAutoAdjustRangeChanged(bool autoAdjust); |
325 | void handleAxisLabelFormatChanged(const QString &format); |
326 | void handleAxisReversedChanged(bool enable); |
327 | void handleAxisFormatterDirty(); |
328 | void handleAxisLabelAutoRotationChanged(float angle); |
329 | void handleAxisTitleVisibilityChanged(bool visible); |
330 | void handleAxisTitleFixedChanged(bool fixed); |
331 | void handleInputViewChanged(QAbstract3DInputHandler::InputView view); |
332 | void handleInputPositionChanged(const QPoint &position); |
333 | void handleSeriesVisibilityChanged(bool visible); |
334 | |
335 | void handleThemeColorStyleChanged(Q3DTheme::ColorStyle style); |
336 | void handleThemeBaseColorsChanged(const QList<QColor> &color); |
337 | void handleThemeBaseGradientsChanged(const QList<QLinearGradient> &gradient); |
338 | void handleThemeSingleHighlightColorChanged(const QColor &color); |
339 | void handleThemeSingleHighlightGradientChanged(const QLinearGradient &gradient); |
340 | void handleThemeMultiHighlightColorChanged(const QColor &color); |
341 | void handleThemeMultiHighlightGradientChanged(const QLinearGradient &gradient); |
342 | void handleThemeTypeChanged(Q3DTheme::Theme theme); |
343 | |
344 | // Renderer callback handlers |
345 | void handleRequestShadowQuality(QAbstract3DGraph::ShadowQuality quality); |
346 | |
347 | void updateCustomItem(); |
348 | |
349 | Q_SIGNALS: |
350 | void shadowQualityChanged(QAbstract3DGraph::ShadowQuality quality); |
351 | void activeThemeChanged(Q3DTheme *activeTheme); |
352 | void selectionModeChanged(QAbstract3DGraph::SelectionFlags mode); |
353 | void needRender(); |
354 | void axisXChanged(QAbstract3DAxis *axis); |
355 | void axisYChanged(QAbstract3DAxis *axis); |
356 | void axisZChanged(QAbstract3DAxis *axis); |
357 | void elementSelected(QAbstract3DGraph::ElementType type); |
358 | void orthoProjectionChanged(bool enabled); |
359 | void aspectRatioChanged(qreal ratio); |
360 | void horizontalAspectRatioChanged(qreal ratio); |
361 | void optimizationHintsChanged(QAbstract3DGraph::OptimizationHints hints); |
362 | void polarChanged(bool enabled); |
363 | void radialLabelOffsetChanged(float offset); |
364 | void reflectionChanged(bool enabled); |
365 | void reflectivityChanged(qreal reflectivity); |
366 | void localeChanged(const QLocale &locale); |
367 | void queriedGraphPositionChanged(const QVector3D &data); |
368 | void marginChanged(qreal margin); |
369 | void themeTypeChanged(); |
370 | |
371 | protected: |
372 | virtual QAbstract3DAxis *createDefaultAxis(QAbstract3DAxis::AxisOrientation orientation); |
373 | QValue3DAxis *createDefaultValueAxis(); |
374 | QCategory3DAxis *createDefaultCategoryAxis(); |
375 | virtual void startRecordingRemovesAndInserts(); |
376 | |
377 | private: |
378 | void setAxisHelper(QAbstract3DAxis::AxisOrientation orientation, QAbstract3DAxis *axis, |
379 | QAbstract3DAxis **axisPtr); |
380 | |
381 | friend class AbstractDeclarative; |
382 | friend class QQuickGraphsItem; |
383 | friend class Bars3DController; |
384 | friend class QAbstract3DGraphPrivate; |
385 | }; |
386 | |
387 | QT_END_NAMESPACE |
388 | |
389 | #endif |
390 | |