Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qgraphicsanchorlayout_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
4#ifndef QGRAPHICSANCHORLAYOUT_P_H
5#define QGRAPHICSANCHORLAYOUT_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtWidgets/private/qtwidgetsglobal_p.h>
19#include <QGraphicsWidget>
20#include <private/qobject_p.h>
21
22#include "qgraphicslayout_p.h"
24#include "qgraph_p.h"
25#include "qsimplex_p.h"
26
27#include <QtGui/private/qgridlayoutengine_p.h>
28
29#include <array>
30
31QT_REQUIRE_CONFIG(graphicsview);
32
34
35/*
36 The public QGraphicsAnchorLayout interface represents an anchorage point
37 as a pair of a <QGraphicsLayoutItem *> and a <Qt::AnchorPoint>.
38
39 Internally though, it has a graph of anchorage points (vertices) and
40 anchors (edges), represented by the AnchorVertex and AnchorData structs
41 respectively.
42*/
43
51{
54
56 : m_item(nullptr), m_edge(Qt::AnchorPoint(0)) {}
57
58 virtual ~AnchorVertex() = default;
59
60#ifdef QT_DEBUG
61 virtual inline QString toString() const;
62#endif
63
66
67 // Current distance from this vertex to the layout edge (Left or Top)
68 // Value is calculated from the current anchors sizes.
70};
71
83
89
99 virtual ~AnchorData();
100
101 virtual void updateChildrenSizes() {}
102 void refreshSizeHints(const QLayoutStyleInfo *styleInfo = nullptr);
103
104#ifdef QT_DEBUG
105 void dump(int indent = 2);
106 inline QString toString() const;
108#endif
109
110 // Anchor is semantically directed
113
114 // Nominal sizes
115 // These are the intrinsic size restrictions for a given item. They are
116 // used as input for the calculation of the actual sizes.
117 // These values are filled by the refreshSizeHints method, based on the
118 // anchor size policy, the size hints of the item it (possibly) represents
119 // and the layout spacing information.
123
126
127 // Calculated sizes
128 // These attributes define which sizes should that anchor be in when the
129 // layout is at its minimum, preferred or maximum sizes. Values are
130 // calculated by the Simplex solver based on the current layout setup.
134
135 // References to the classes that represent this anchor in the public world
136 // An anchor may represent a LayoutItem, it may also be accessible externally
137 // through a GraphicsAnchor "handler".
140
141 uint type : 2; // either Normal, Sequential or Parallel
142 uint isLayoutAnchor : 1; // if this anchor is an internal layout anchor
145 uint dependency : 2; // either Independent, Master or Slave
146};
147
148#ifdef QT_DEBUG
149inline QString AnchorData::toString() const
150{
151 return QString::fromLatin1("Anchor(%1)").arg(name);
152}
153#endif
154
156{
157 SequentialAnchorData(const QList<AnchorVertex *> &vertices, const QList<AnchorData *> &edges)
158 : AnchorData(), m_edges(edges)
159 {
161 isVertical = m_edges.at(0)->isVertical;
162#ifdef QT_DEBUG
163 name = QString::fromLatin1("%1 -- %2").arg(vertices.first()->toString(), vertices.last()->toString());
164#else
165 Q_UNUSED(vertices);
166#endif
167 }
168
169 virtual void updateChildrenSizes() override;
170 void calculateSizeHints();
171
172 const QList<AnchorData *> m_edges; // keep the list of edges too.
173};
174
176{
178 : AnchorData(), firstEdge(first), secondEdge(second)
179 {
181 isVertical = first->isVertical;
182
183 // This assert whether the child anchors share their vertices
184 Q_ASSERT(((first->from == second->from) && (first->to == second->to)) ||
185 ((first->from == second->to) && (first->to == second->from)));
186
187 // Our convention will be that the parallel group anchor will have the same
188 // direction as the first anchor.
189 from = first->from;
190 to = first->to;
191#ifdef QT_DEBUG
192 name = QString::fromLatin1("%1 | %2").arg(first->toString(), second->toString());
193#endif
194 }
195
196 virtual void updateChildrenSizes() override;
197 bool calculateSizeHints();
198
199 bool secondForward() const {
200 // We have the convention that the first children will define the direction of the
201 // pararell group. Note that we can't rely on 'this->from' or 'this->to' because they
202 // might be changed by vertex simplification.
203 return firstEdge->from == secondEdge->from;
204 }
205
208
209 QList<QSimplexConstraint *> m_firstConstraints;
210 QList<QSimplexConstraint *> m_secondConstraints;
211};
212
218
221
223 QList<AnchorData *> m_firstAnchors;
224 QList<AnchorData *> m_secondAnchors;
225
226#ifdef QT_DEBUG
227 inline QString toString() const override
228 {
229 return QString::fromLatin1("(%1, %2)").arg(m_first->toString(), m_second->toString());
230 }
231#endif
232};
233
234#ifdef QT_DEBUG
235inline QString AnchorVertex::toString() const
236{
237 using namespace Qt::StringLiterals;
238
239 if (!m_item)
240 return QString::fromLatin1("NULL_%1").arg(quintptr(this));
241
242 QString edge;
243 switch (m_edge) {
244 case Qt::AnchorLeft:
245 edge = "Left"_L1;
246 break;
248 edge = "HorizontalCenter"_L1;
249 break;
250 case Qt::AnchorRight:
251 edge = "Right"_L1;
252 break;
253 case Qt::AnchorTop:
254 edge = "Top"_L1;
255 break;
257 edge = "VerticalCenter"_L1;
258 break;
259 case Qt::AnchorBottom:
260 edge = "Bottom"_L1;
261 break;
262 default:
263 edge = "None"_L1;
264 break;
265 }
266 QString itemName;
267 if (m_item->isLayout()) {
268 itemName = "layout"_L1;
269 } else {
271 itemName = item->data(0).toString();
272 }
273 }
274 edge.insert(0, "%1_"_L1);
275 return edge.arg(itemName);
276}
277#endif
278
291{
292public:
294
296#ifdef QT_DEBUG
297 QString toString() const;
298#endif
299 QSet<AnchorData *> positives;
300 QSet<AnchorData *> negatives;
301};
302} // namespace QtGraphicsAnchorLayout
303using namespace QtGraphicsAnchorLayout;
304
306
312{
313 Q_DECLARE_PUBLIC(QGraphicsAnchor)
314
315public:
316 explicit QGraphicsAnchorPrivate(int version = QObjectPrivateVersion);
318
319 void setSpacing(qreal value);
320 void unsetSpacing();
321 qreal spacing() const;
322
324
326 { return q->d_func(); }
327
330
331 // Size information for user controlled anchor
334
335 uint hasSize : 1; // if false, get size from style.
336};
337
338
339
340
347{
348 Q_DECLARE_PUBLIC(QGraphicsAnchorLayout)
349
350public:
351 // When the layout geometry is different from its Minimum, Preferred
352 // or Maximum values, interpolation is used to calculate the geometries
353 // of the items.
354 //
355 // Interval represents which interpolation interval are we operating in.
356 enum Interval {
357 MinimumToMinPreferred = 0,
360 MaxPreferredToMaximum
361 };
362
363 typedef Qt::Orientation Orientation [[deprecated]];
364 [[deprecated]] static inline constexpr Qt::Orientation Horizontal = Qt::Horizontal;
365 [[deprecated]] static inline constexpr Qt::Orientation Vertical = Qt::Vertical;
366
368
370 {
371 return q ? q->d_func() : nullptr;
372 }
373
374 static Qt::AnchorPoint oppositeEdge(
375 Qt::AnchorPoint edge);
376
377 static Qt::Orientation edgeOrientation(Qt::AnchorPoint edge) noexcept;
378
380 {
381 if (orientation == Qt::Vertical && int(edge) <= 2)
382 return (Qt::AnchorPoint)(edge + 3);
383 else if (orientation == Qt::Horizontal && int(edge) >= 3) {
384 return (Qt::AnchorPoint)(edge - 3);
385 }
386 return edge;
387 }
388
389 // Init methods
390 void createLayoutEdges();
391 void deleteLayoutEdges();
392 void createItemEdges(QGraphicsLayoutItem *item);
393 void createCenterAnchors(QGraphicsLayoutItem *item, Qt::AnchorPoint centerEdge);
394 void removeCenterAnchors(QGraphicsLayoutItem *item, Qt::AnchorPoint centerEdge, bool substitute = true);
395 void removeCenterConstraints(QGraphicsLayoutItem *item, Qt::Orientation orientation);
396
398 {
400 if (!data->graphicsAnchor) {
401 data->graphicsAnchor = new QGraphicsAnchor(q);
402 data->graphicsAnchor->d_func()->data = data;
403 }
404 return data->graphicsAnchor;
405 }
406
407 // function used by the 4 API functions
408 QGraphicsAnchor *addAnchor(QGraphicsLayoutItem *firstItem,
409 Qt::AnchorPoint firstEdge,
410 QGraphicsLayoutItem *secondItem,
411 Qt::AnchorPoint secondEdge,
412 qreal *spacing = nullptr);
413
414 // Helper for Anchor Manipulation methods
415 void addAnchor_helper(QGraphicsLayoutItem *firstItem,
416 Qt::AnchorPoint firstEdge,
417 QGraphicsLayoutItem *secondItem,
418 Qt::AnchorPoint secondEdge,
420
421 QGraphicsAnchor *getAnchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge,
422 QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge);
423
424 void removeAnchor(AnchorVertex *firstVertex, AnchorVertex *secondVertex);
425 void removeAnchor_helper(AnchorVertex *v1, AnchorVertex *v2);
426
427 void removeAnchors(QGraphicsLayoutItem *item);
428
429 void removeVertex(QGraphicsLayoutItem *item, Qt::AnchorPoint edge);
430
431 void correctEdgeDirection(QGraphicsLayoutItem *&firstItem,
432 Qt::AnchorPoint &firstEdge,
433 QGraphicsLayoutItem *&secondItem,
434 Qt::AnchorPoint &secondEdge);
435
436 QLayoutStyleInfo &styleInfo() const;
437
438 AnchorData *addAnchorMaybeParallel(AnchorData *newAnchor, bool *feasible);
439
440 // Activation
441 void calculateGraphs();
442 void calculateGraphs(Qt::Orientation orientation);
443
444 // Simplification
445 bool simplifyGraph(Qt::Orientation orientation);
446 bool simplifyVertices(Qt::Orientation orientation);
447 bool simplifyGraphIteration(Qt::Orientation orientation, bool *feasible);
448
449 bool replaceVertex(Qt::Orientation orientation, AnchorVertex *oldV,
450 AnchorVertex *newV, const QList<AnchorData *> &edges);
451
452
453 void restoreSimplifiedGraph(Qt::Orientation orientation);
454 void restoreSimplifiedAnchor(AnchorData *edge);
455 void restoreSimplifiedConstraints(ParallelAnchorData *parallel);
456 void restoreVertices(Qt::Orientation orientation);
457
458 bool calculateTrunk(Qt::Orientation orientation, const GraphPath &trunkPath,
459 const QList<QSimplexConstraint *> &constraints,
460 const QList<AnchorData *> &variables);
461 bool calculateNonTrunk(const QList<QSimplexConstraint *> &constraints,
462 const QList<AnchorData *> &variables);
463
464 // Support functions for calculateGraph()
465 void refreshAllSizeHints(Qt::Orientation orientation);
466 void findPaths(Qt::Orientation orientation);
467 void constraintsFromPaths(Qt::Orientation orientation);
468 void updateAnchorSizes(Qt::Orientation orientation);
469 QList<QSimplexConstraint *> constraintsFromSizeHints(const QList<AnchorData *> &anchors);
470 struct GraphParts {
471 QList<QSimplexConstraint *> trunkConstraints;
472 QList<QSimplexConstraint *> nonTrunkConstraints;
473 };
474 GraphParts getGraphParts(Qt::Orientation orientation);
475 void identifyFloatItems(const QSet<AnchorData *> &visited, Qt::Orientation orientation);
476 void identifyNonFloatItems_helper(const AnchorData *ad, QSet<QGraphicsLayoutItem *> *nonFloatingItemsIdentifiedSoFar);
477
478 inline AnchorVertex *internalVertex(const QPair<QGraphicsLayoutItem*, Qt::AnchorPoint> &itemEdge) const
479 {
480 return m_vertexList.value(itemEdge).first;
481 }
482
484 {
485 return internalVertex(qMakePair(const_cast<QGraphicsLayoutItem *>(item), edge));
486 }
487
488 inline void changeLayoutVertex(Qt::Orientation orientation, AnchorVertex *oldV, AnchorVertex *newV)
489 {
490 if (layoutFirstVertex[orientation] == oldV)
491 layoutFirstVertex[orientation] = newV;
492 else if (layoutCentralVertex[orientation] == oldV)
493 layoutCentralVertex[orientation] = newV;
494 else if (layoutLastVertex[orientation] == oldV)
495 layoutLastVertex[orientation] = newV;
496 }
497
498
499 AnchorVertex *addInternalVertex(QGraphicsLayoutItem *item, Qt::AnchorPoint edge);
500 void removeInternalVertex(QGraphicsLayoutItem *item, Qt::AnchorPoint edge);
501
502 // Geometry interpolation methods
503 void setItemsGeometries(const QRectF &geom);
504
505 void calculateVertexPositions(Qt::Orientation orientation);
506 void setupEdgesInterpolation(Qt::Orientation orientation);
507 void interpolateEdge(AnchorVertex *base, AnchorData *edge);
508
509 // Linear Programming solver methods
510 bool solveMinMax(const QList<QSimplexConstraint *> &constraints,
511 const GraphPath &path, qreal *min, qreal *max);
512 bool solvePreferred(const QList<QSimplexConstraint *> &constraints,
513 const QList<AnchorData *> &variables);
514 bool hasConflicts() const;
515
516#ifdef QT_DEBUG
517 void dumpGraph(const QString &name = QString());
518#endif
519
520
521 QHVContainer<qreal> spacings = {-1, -1};
522 // Size hints from simplex engine
523 QHVContainer<std::array<qreal, 3>> sizeHints = {{-1, -1, -1}, {-1, -1, -1}};
524
525 // Items
526 QList<QGraphicsLayoutItem *> items;
527
528 // Mapping between high level anchorage points (Item, Edge) to low level
529 // ones (Graph Vertices)
530
531 QHash<QPair<QGraphicsLayoutItem*, Qt::AnchorPoint>, QPair<AnchorVertex *, int> > m_vertexList;
532
533 // Internal graph of anchorage points and anchors, for both orientations
534 QHVContainer<Graph<AnchorVertex, AnchorData>> graph;
535
536 QHVContainer<AnchorVertex *> layoutFirstVertex = {};
537 QHVContainer<AnchorVertex *> layoutCentralVertex = {};
538 QHVContainer<AnchorVertex *> layoutLastVertex = {};
539
540 // Combined anchors in order of creation
541 QHVContainer<QList<AnchorVertexPair *>> simplifiedVertices;
542 QHVContainer<QList<AnchorData *>> anchorsFromSimplifiedVertices;
543
544 // Graph paths and constraints, for both orientations
545 QHVContainer<QMultiHash<AnchorVertex *, GraphPath>> graphPaths;
546 QHVContainer<QList<QSimplexConstraint *>> constraints;
547 QHVContainer<QList<QSimplexConstraint *>> itemCenterConstraints;
548
549 // The interpolation interval and progress based on the current size
550 // as well as the key values (minimum, preferred and maximum)
551 QHVContainer<Interval> interpolationInterval;
552 QHVContainer<qreal> interpolationProgress = {-1, -1};
553
554 QHVContainer<bool> graphHasConflicts = {};
555 QHVContainer<QSet<QGraphicsLayoutItem *>> m_floatItems;
556
557#if defined(QT_DEBUG) || defined(QT_BUILD_INTERNAL)
558 QHVContainer<bool> lastCalculationUsedSimplex;
559#endif
560
562 mutable uint styleInfoDirty : 1;
564
566};
567
569
570#endif
QHVContainer< Interval > interpolationInterval
QHVContainer< Graph< AnchorVertex, AnchorData > > graph
QHVContainer< QList< QSimplexConstraint * > > constraints
QHash< QPair< QGraphicsLayoutItem *, Qt::AnchorPoint >, QPair< AnchorVertex *, int > > m_vertexList
QHVContainer< QList< AnchorData * > > anchorsFromSimplifiedVertices
QHVContainer< QList< AnchorVertexPair * > > simplifiedVertices
static Qt::AnchorPoint pickEdge(Qt::AnchorPoint edge, Qt::Orientation orientation)
QHVContainer< QMultiHash< AnchorVertex *, GraphPath > > graphPaths
static QGraphicsAnchorLayoutPrivate * get(QGraphicsAnchorLayout *q)
QGraphicsAnchor * acquireGraphicsAnchor(AnchorData *data)
void changeLayoutVertex(Qt::Orientation orientation, AnchorVertex *oldV, AnchorVertex *newV)
QHVContainer< QList< QSimplexConstraint * > > itemCenterConstraints
QHVContainer< QSet< QGraphicsLayoutItem * > > m_floatItems
QList< QGraphicsLayoutItem * > items
AnchorVertex * internalVertex(const QGraphicsLayoutItem *item, Qt::AnchorPoint edge) const
AnchorVertex * internalVertex(const QPair< QGraphicsLayoutItem *, Qt::AnchorPoint > &itemEdge) const
The QGraphicsAnchorLayout class provides a layout where one can anchor widgets together in Graphics V...
void setSizePolicy(QSizePolicy::Policy policy)
QGraphicsAnchorPrivate(int version=QObjectPrivateVersion)
static QGraphicsAnchorPrivate * get(QGraphicsAnchor *q)
QGraphicsAnchorLayoutPrivate * layoutPrivate
The QGraphicsAnchor class represents an anchor between two items in a QGraphicsAnchorLayout.
The QGraphicsItem class is the base class for all graphical items in a QGraphicsScene.
QVariant data(int key) const
Returns this item's custom data for the key key as a QVariant.
The QGraphicsLayoutItem class can be inherited to allow your custom items to be managed by layouts.
QGraphicsItem * graphicsItem() const
Returns the QGraphicsItem that this layout item represents.
bool isLayout() const
Returns true if this QGraphicsLayoutItem is a layout (e.g., is inherited by an object that arranges o...
\inmodule QtCore\reentrant
Definition qrect.h:484
Policy
This enum describes the various per-dimension sizing types used when constructing a QSizePolicy.
Definition qsizepolicy.h:29
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5871
QString arg(qlonglong a, int fieldwidth=0, int base=10, QChar fillChar=u' ') const
Definition qstring.cpp:8870
QString & insert(qsizetype i, QChar c)
Definition qstring.cpp:3132
QString toString() const
Returns the variant as a QString if the variant has a userType() including, but not limited to:
QSimplexConstraint * constraint(const GraphPath &path) const
qreal spacing
Combined button and popup list for selecting options.
Definition qcompare.h:63
Orientation
Definition qnamespace.h:98
@ Horizontal
Definition qnamespace.h:99
@ Vertical
Definition qnamespace.h:100
AnchorPoint
@ AnchorRight
@ AnchorVerticalCenter
@ AnchorBottom
@ AnchorTop
@ AnchorHorizontalCenter
@ AnchorLeft
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
@ QObjectPrivateVersion
Definition qobject_p.h:61
GLint GLfloat GLfloat GLfloat v2
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum type
GLint GLfloat GLfloat v1
GLuint name
GLint first
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLsizei const GLchar *const * path
QT_BEGIN_NAMESPACE constexpr decltype(auto) qMakePair(T1 &&value1, T2 &&value2) noexcept(noexcept(std::make_pair(std::forward< T1 >(value1), std::forward< T2 >(value2))))
Definition qpair.h:19
QQuickAnchors * anchors(QQuickItem *item)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
static QString dump(const QByteArray &)
#define Q_AUTOTEST_EXPORT
#define QT_REQUIRE_CONFIG(feature)
#define Q_UNUSED(x)
@ Q_RELOCATABLE_TYPE
Definition qtypeinfo.h:158
#define Q_DECLARE_TYPEINFO(TYPE, FLAGS)
Definition qtypeinfo.h:180
size_t quintptr
Definition qtypes.h:167
unsigned int uint
Definition qtypes.h:34
double qreal
Definition qtypes.h:187
static const uint base
Definition qurlidna.cpp:20
QObject::connect nullptr
QGraphicsItem * item
QSizePolicy policy
char * toString(const MyType &t)
[31]
QList< QSimplexConstraint * > nonTrunkConstraints
void refreshSizeHints(const QLayoutStyleInfo *styleInfo=nullptr)
AnchorVertexPair(AnchorVertex *v1, AnchorVertex *v2, AnchorData *data)
AnchorVertex(QGraphicsLayoutItem *item, Qt::AnchorPoint edge)
ParallelAnchorData(AnchorData *first, AnchorData *second)
SequentialAnchorData(const QList< AnchorVertex * > &vertices, const QList< AnchorData * > &edges)
Definition moc.h:23