Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qgraphicsscene_p.h
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#ifndef QGRAPHICSSCENE_P_H
6#define QGRAPHICSSCENE_P_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists for the convenience
13// of other Qt classes. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include <QtWidgets/private/qtwidgetsglobal_p.h>
20#include "qgraphicsscene.h"
21
23#include "qgraphicsview.h"
26
27#include <private/qobject_p.h>
28#include <QtCore/qbitarray.h>
29#include <QtCore/qlist.h>
30#include <QtCore/qmap.h>
31#include <QtCore/qset.h>
32#include <QtGui/qfont.h>
33#include <QtGui/qpalette.h>
34#include <QtWidgets/qstyle.h>
35#include <QtWidgets/qstyleoption.h>
36
37#include <set>
38#include <tuple>
39
41
42QT_BEGIN_NAMESPACE
43
44class QGraphicsSceneIndex;
45class QGraphicsView;
46class QGraphicsWidget;
47
48class Q_AUTOTEST_EXPORT QGraphicsScenePrivate : public QObjectPrivate
49{
50 Q_DECLARE_PUBLIC(QGraphicsScene)
51public:
52 QGraphicsScenePrivate();
53 void init();
54
55 static QGraphicsScenePrivate *get(QGraphicsScene *q);
56
57 int changedSignalIndex;
58 int processDirtyItemsIndex;
59 int polishItemsIndex;
60
61 QGraphicsScene::ItemIndexMethod indexMethod;
62 QGraphicsSceneIndex *index;
63
64 int lastItemCount;
65
66 QRectF sceneRect;
67
68 quint32 hasSceneRect : 1;
69 quint32 dirtyGrowingItemsBoundingRect : 1;
70 quint32 updateAll : 1;
71 quint32 calledEmitUpdated : 1;
72 quint32 processDirtyItemsEmitted : 1;
73 quint32 needSortTopLevelItems : 1;
74 quint32 holesInTopLevelSiblingIndex : 1;
75 quint32 topLevelSequentialOrdering : 1;
76 quint32 scenePosDescendantsUpdatePending : 1;
77 quint32 stickyFocus : 1;
78 quint32 hasFocus : 1;
79 quint32 lastMouseGrabberItemHasImplicitMouseGrab : 1;
80 quint32 allItemsIgnoreHoverEvents : 1;
81 quint32 allItemsUseDefaultCursor : 1;
82 quint32 painterStateProtection : 1;
83 quint32 sortCacheEnabled : 1; // for compatibility
84 quint32 allItemsIgnoreTouchEvents : 1;
85 quint32 focusOnTouch : 1;
86 quint32 padding : 14;
87
88 qreal minimumRenderSize;
89
90 QRectF growingItemsBoundingRect;
91
92 void _q_emitUpdated();
93
94 struct UpdatedRectsCmp
95 {
96 bool operator() (const QRectF &a, const QRectF &b) const noexcept
97 {
98 return std::make_tuple(a.y(), a.x(), a.height(), a.width())
99 < std::make_tuple(b.y(), b.x(), b.height(), b.width());
100 }
101 };
102
103 // std::set was used here instead of std::unordered_set due to requiring only a comparator and
104 // showing equivalent performance in empirical measurements within the ranges of interest...
105 std::set<QRectF, UpdatedRectsCmp> updatedRects;
106
107 QPainterPath selectionArea;
108 int selectionChanging;
109 QSet<QGraphicsItem *> selectedItems;
110 QList<QGraphicsItem *> unpolishedItems;
111 QList<QGraphicsItem *> topLevelItems;
112
113 QHash<QGraphicsItem *, QPointF> movingItemsInitialPositions;
114 void registerTopLevelItem(QGraphicsItem *item);
115 void unregisterTopLevelItem(QGraphicsItem *item);
116 void _q_updateLater();
117 void _q_polishItems();
118
119 void _q_processDirtyItems();
120
121 QSet<QGraphicsItem *> scenePosItems;
122 void setScenePosItemEnabled(QGraphicsItem *item, bool enabled);
123 void registerScenePosItem(QGraphicsItem *item);
124 void unregisterScenePosItem(QGraphicsItem *item);
125 void _q_updateScenePosDescendants();
126
127 void removeItemHelper(QGraphicsItem *item);
128
129 QBrush backgroundBrush;
130 QBrush foregroundBrush;
131
132 quint32 rectAdjust;
133 QGraphicsItem *focusItem;
134 QGraphicsItem *lastFocusItem;
135 QGraphicsItem *passiveFocusItem;
136 QGraphicsWidget *tabFocusFirst;
137 QGraphicsItem *activePanel;
138 QGraphicsItem *lastActivePanel;
139 int activationRefCount;
140 int childExplicitActivation;
141 void setActivePanelHelper(QGraphicsItem *item, bool duringActivationEvent);
142 void setFocusItemHelper(QGraphicsItem *item, Qt::FocusReason focusReason,
143 bool emitFocusChanged = true);
144
145 QList<QGraphicsWidget *> popupWidgets;
146 void addPopup(QGraphicsWidget *widget);
147 void removePopup(QGraphicsWidget *widget, bool itemIsDying = false);
148
149 QGraphicsItem *lastMouseGrabberItem;
150 QList<QGraphicsItem *> mouseGrabberItems;
151 void grabMouse(QGraphicsItem *item, bool implicit = false);
152 void ungrabMouse(QGraphicsItem *item, bool itemIsDying = false);
153 void clearMouseGrabber();
154
155 QList<QGraphicsItem *> keyboardGrabberItems;
156 void grabKeyboard(QGraphicsItem *item);
157 void ungrabKeyboard(QGraphicsItem *item, bool itemIsDying = false);
158 void clearKeyboardGrabber();
159
160 QGraphicsItem *dragDropItem;
161 QGraphicsWidget *enterWidget;
162 Qt::DropAction lastDropAction;
163 QList<QGraphicsItem *> cachedItemsUnderMouse;
164 QList<QGraphicsItem *> hoverItems;
165 QPointF lastSceneMousePos;
166 void enableMouseTrackingOnViews();
167 QMap<Qt::MouseButton, QPointF> mouseGrabberButtonDownPos;
168 QMap<Qt::MouseButton, QPointF> mouseGrabberButtonDownScenePos;
169 QMap<Qt::MouseButton, QPoint> mouseGrabberButtonDownScreenPos;
170 QList<QGraphicsItem *> itemsAtPosition(const QPoint &screenPos,
171 const QPointF &scenePos,
172 QWidget *widget) const;
173 void storeMouseButtonsForMouseGrabber(QGraphicsSceneMouseEvent *event);
174
175 QList<QGraphicsView *> views;
176 void addView(QGraphicsView *view);
177 void removeView(QGraphicsView *view);
178
179 QMultiMap<QGraphicsItem *, QGraphicsItem *> sceneEventFilters;
180 void installSceneEventFilter(QGraphicsItem *watched, QGraphicsItem *filter);
181 void removeSceneEventFilter(QGraphicsItem *watched, QGraphicsItem *filter);
182 bool filterDescendantEvent(QGraphicsItem *item, QEvent *event);
183 bool filterEvent(QGraphicsItem *item, QEvent *event);
184 bool sendEvent(QGraphicsItem *item, QEvent *event);
185
186 bool dispatchHoverEvent(QGraphicsSceneHoverEvent *hoverEvent);
187 bool itemAcceptsHoverEvents_helper(const QGraphicsItem *item) const;
188 void leaveScene(QWidget *viewport);
189
190 void cloneDragDropEvent(QGraphicsSceneDragDropEvent *dest,
191 QGraphicsSceneDragDropEvent *source);
192 void sendDragDropEvent(QGraphicsItem *item,
193 QGraphicsSceneDragDropEvent *dragDropEvent);
194 void sendHoverEvent(QEvent::Type type, QGraphicsItem *item,
195 QGraphicsSceneHoverEvent *hoverEvent);
196 void sendMouseEvent(QGraphicsSceneMouseEvent *mouseEvent);
197 void mousePressEventHandler(QGraphicsSceneMouseEvent *mouseEvent);
198 QGraphicsWidget *windowForItem(const QGraphicsItem *item) const;
199
200 void drawItemHelper(QGraphicsItem *item, QPainter *painter,
201 const QStyleOptionGraphicsItem *option, QWidget *widget,
202 bool painterStateProtection);
203
204 void drawItems(QPainter *painter, const QTransform *const viewTransform,
205 QRegion *exposedRegion, QWidget *widget);
206
207 void drawSubtreeRecursive(QGraphicsItem *item, QPainter *painter, const QTransform *const,
208 QRegion *exposedRegion, QWidget *widget, qreal parentOpacity = qreal(1.0),
209 const QTransform *const effectTransform = nullptr);
210 void draw(QGraphicsItem *, QPainter *, const QTransform *const, const QTransform *const,
211 QRegion *, QWidget *, qreal, const QTransform *const, bool, bool);
212
213 void markDirty(QGraphicsItem *item, const QRectF &rect = QRectF(), bool invalidateChildren = false,
214 bool force = false, bool ignoreOpacity = false, bool removingItemFromScene = false,
215 bool updateBoundingRect = false);
216 void processDirtyItemsRecursive(QGraphicsItem *item, bool dirtyAncestorContainsChildren = false,
217 qreal parentOpacity = qreal(1.0));
218
219 inline void resetDirtyItem(QGraphicsItem *item, bool recursive = false)
220 {
221 Q_ASSERT(item);
222 item->d_ptr->dirty = 0;
223 item->d_ptr->paintedViewBoundingRectsNeedRepaint = 0;
224 item->d_ptr->geometryChanged = 0;
225 if (!item->d_ptr->dirtyChildren)
226 recursive = false;
227 item->d_ptr->dirtyChildren = 0;
228 item->d_ptr->needsRepaint = QRectF();
229 item->d_ptr->allChildrenDirty = 0;
230 item->d_ptr->fullUpdatePending = 0;
231 item->d_ptr->ignoreVisible = 0;
232 item->d_ptr->ignoreOpacity = 0;
233#if QT_CONFIG(graphicseffect)
234 QGraphicsEffect::ChangeFlags flags;
235 if (item->d_ptr->notifyBoundingRectChanged) {
236 flags |= QGraphicsEffect::SourceBoundingRectChanged;
237 item->d_ptr->notifyBoundingRectChanged = 0;
238 }
239 if (item->d_ptr->notifyInvalidated) {
240 flags |= QGraphicsEffect::SourceInvalidated;
241 item->d_ptr->notifyInvalidated = 0;
242 }
243#endif // QT_CONFIG(graphicseffect)
244 if (recursive) {
245 for (int i = 0; i < item->d_ptr->children.size(); ++i)
246 resetDirtyItem(item->d_ptr->children.at(i), recursive);
247 }
248#if QT_CONFIG(graphicseffect)
249 if (flags && item->d_ptr->graphicsEffect)
250 item->d_ptr->graphicsEffect->sourceChanged(flags);
251#endif // QT_CONFIG(graphicseffect)
252 }
253
254 inline void ensureSortedTopLevelItems()
255 {
256 if (needSortTopLevelItems) {
257 std::sort(topLevelItems.begin(), topLevelItems.end(), qt_notclosestLeaf);
258 topLevelSequentialOrdering = false;
259 needSortTopLevelItems = false;
260 }
261 }
262
263 void ensureSequentialTopLevelSiblingIndexes();
264
265 QStyle *style;
266 QFont font;
267 void setFont_helper(const QFont &font);
268 void resolveFont();
269 void updateFont(const QFont &font);
270 QPalette palette;
271 void setPalette_helper(const QPalette &palette);
272 void resolvePalette();
273 void updatePalette(const QPalette &palette);
274
275 QStyleOptionGraphicsItem styleOptionTmp;
276
277 QMap<int, QEventPoint> sceneCurrentTouchPoints;
278 QMap<int, QGraphicsItem *> itemForTouchPointId;
279 static void updateTouchPointsForItem(QGraphicsItem *item, QTouchEvent *touchEvent);
280 int findClosestTouchPointId(const QPointF &scenePos);
281 void touchEventHandler(QTouchEvent *touchEvent);
282 bool sendTouchBeginEvent(QGraphicsItem *item, QTouchEvent *touchEvent);
283 void enableTouchEventsOnViews();
284
285 QList<QGraphicsObject *> cachedTargetItems;
286#ifndef QT_NO_GESTURES
287 QHash<QGraphicsObject *, QSet<QGesture *> > cachedItemGestures;
288 QHash<QGraphicsObject *, QSet<QGesture *> > cachedAlreadyDeliveredGestures;
289 QHash<QGesture *, QGraphicsObject *> gestureTargets;
290 QHash<Qt::GestureType, int> grabbedGestures;
291 void gestureEventHandler(QGestureEvent *event);
292 void gestureTargetsAtHotSpots(const QSet<QGesture *> &gestures,
293 Qt::GestureFlag flag,
294 QHash<QGraphicsObject *, QSet<QGesture *> > *targets,
295 QSet<QGraphicsObject *> *itemsSet = nullptr,
296 QSet<QGesture *> *normal = nullptr,
297 QSet<QGesture *> *conflicts = nullptr);
298 void cancelGesturesForChildren(QGesture *original);
299 void grabGesture(QGraphicsItem *, Qt::GestureType gesture);
300 void ungrabGesture(QGraphicsItem *, Qt::GestureType gesture);
301#endif // QT_NO_GESTURES
302
303 void updateInputMethodSensitivityInViews();
304
305 QList<QGraphicsItem *> modalPanels;
306 void enterModal(QGraphicsItem *item,
307 QGraphicsItem::PanelModality panelModality = QGraphicsItem::NonModal);
308 void leaveModal(QGraphicsItem *item);
309};
310
311// QRectF::intersects() returns false always if either the source or target
312// rectangle's width or height are 0. This works around that problem.
313static inline void _q_adjustRect(QRectF *rect)
314{
315 Q_ASSERT(rect);
316 if (!rect->width())
317 rect->adjust(qreal(-0.00001), 0, qreal(0.00001), 0);
318 if (!rect->height())
319 rect->adjust(0, qreal(-0.00001), 0, qreal(0.00001));
320}
321
322static inline QRectF adjustedItemBoundingRect(const QGraphicsItem *item)
323{
324 Q_ASSERT(item);
325 QRectF boundingRect(item->boundingRect());
326 _q_adjustRect(&boundingRect);
327 return boundingRect;
328}
329
330static inline QRectF adjustedItemEffectiveBoundingRect(const QGraphicsItem *item)
331{
332 Q_ASSERT(item);
333 QRectF boundingRect(QGraphicsItemPrivate::get(item)->effectiveBoundingRect());
334 _q_adjustRect(&boundingRect);
335 return boundingRect;
336}
337
338QT_END_NAMESPACE
339
340#endif
The QAbstractGraphicsShapeItem class provides a common base for all path items.
The QGraphicsEllipseItem class provides an ellipse item that you can add to a QGraphicsScene.
QHash< const QGraphicsItem *, QMap< int, QVariant > > data
The QGraphicsItemGroup class provides a container that treats a group of items as a single item.
The QGraphicsItem class is the base class for all graphical items in a QGraphicsScene.
The QGraphicsLineItem class provides a line item that you can add to a QGraphicsScene.
The QGraphicsObject class provides a base class for all graphics items that require signals,...
QGraphicsPixmapItem::ShapeMode shapeMode
Qt::TransformationMode transformationMode
The QGraphicsPixmapItem class provides a pixmap item that you can add to a QGraphicsScene.
The QGraphicsPolygonItem class provides a polygon item that you can add to a QGraphicsScene.
The QGraphicsRectItem class provides a rectangle item that you can add to a QGraphicsScene.
The QGraphicsScene class provides a surface for managing a large number of 2D graphical items.
The QGraphicsSimpleTextItem class provides a simple text item that you can add to a QGraphicsScene.
void _q_updateBoundingRect(const QSizeF &)
bool _q_mouseOnEdge(QGraphicsSceneMouseEvent *)
QWidgetTextControl * control
QWidgetTextControl * textControl() const
void sendControlEvent(QEvent *e)
The QGraphicsTextItem class provides a text item that you can add to a QGraphicsScene to display form...
friend class QPainter
\inmodule QtGui
friend class QWidget
Definition qpainter.h:431
\inmodule QtCore\reentrant
Definition qpoint.h:231
The QPolygonF class provides a list of points using floating point precision.
Definition qpolygon.h:96
Q_CORE_EXPORT QDebug operator<<(QDebug debug, QDir::Filters filters)
Definition qdir.cpp:2568
static void formatGraphicsItemHelper(QDebug debug, const QGraphicsItem *item)
bool _qt_movableAncestorIsSelected(const QGraphicsItem *item)
static QRectF setupTextLayout(QTextLayout *layout)
QDebug operator<<(QDebug debug, const QGraphicsObject *item)
static QPainterPath qt_graphicsItem_shapeFromPath(const QPainterPath &path, const QPen &pen)
QDebug operator<<(QDebug debug, const QGraphicsItem *item)
static bool qt_QGraphicsItem_isObscured(const QGraphicsItem *item, const QGraphicsItem *other, const QRectF &rect)
QT_REQUIRE_CONFIG(graphicsview)
static QRectF adjustedItemBoundingRect(const QGraphicsItem *item)
static QRectF adjustedItemEffectiveBoundingRect(const QGraphicsItem *item)
static void _q_adjustRect(QRectF *rect)
QDebug operator<<(QDebug debug, QIODevice::OpenMode modes)