Qt 6.x
The Qt SDK
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{
53 : m_item(item), m_edge(edge) {}
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
78 enum Type {
79 Normal = 0,
82 };
83
87 Slave
88 };
89
92 minSize(0), prefSize(0), maxSize(0),
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{
158 : AnchorData(), m_children(vertices), m_edges(edges)
159 {
162#ifdef QT_DEBUG
163 name = QString::fromLatin1("%1 -- %2").arg(vertices.first()->toString(), vertices.last()->toString());
164#endif
165 }
166
167 virtual void updateChildrenSizes() override;
168 void calculateSizeHints();
169
170 QList<AnchorVertex *> m_children; // list of vertices in the sequence
171 QList<AnchorData *> m_edges; // keep the list of edges too.
172};
173
175{
177 : AnchorData(), firstEdge(first), secondEdge(second)
178 {
180 isVertical = first->isVertical;
181
182 // This assert whether the child anchors share their vertices
183 Q_ASSERT(((first->from == second->from) && (first->to == second->to)) ||
184 ((first->from == second->to) && (first->to == second->from)));
185
186 // Our convention will be that the parallel group anchor will have the same
187 // direction as the first anchor.
188 from = first->from;
189 to = first->to;
190#ifdef QT_DEBUG
191 name = QString::fromLatin1("%1 | %2").arg(first->toString(), second->toString());
192#endif
193 }
194
195 virtual void updateChildrenSizes() override;
196 bool calculateSizeHints();
197
198 bool secondForward() const {
199 // We have the convention that the first children will define the direction of the
200 // pararell group. Note that we can't rely on 'this->from' or 'this->to' because they
201 // might be changed by vertex simplification.
202 return firstEdge->from == secondEdge->from;
203 }
204
207
210};
211
215 {
216 }
217
220
224
225#ifdef QT_DEBUG
226 inline QString toString() const override
227 {
228 return QString::fromLatin1("(%1, %2)").arg(m_first->toString(), m_second->toString());
229 }
230#endif
231};
232
233#ifdef QT_DEBUG
234inline QString AnchorVertex::toString() const
235{
236 using namespace Qt::StringLiterals;
237
238 if (!m_item)
239 return QString::fromLatin1("NULL_%1").arg(quintptr(this));
240
241 QString edge;
242 switch (m_edge) {
243 case Qt::AnchorLeft:
244 edge = "Left"_L1;
245 break;
247 edge = "HorizontalCenter"_L1;
248 break;
249 case Qt::AnchorRight:
250 edge = "Right"_L1;
251 break;
252 case Qt::AnchorTop:
253 edge = "Top"_L1;
254 break;
256 edge = "VerticalCenter"_L1;
257 break;
258 case Qt::AnchorBottom:
259 edge = "Bottom"_L1;
260 break;
261 default:
262 edge = "None"_L1;
263 break;
264 }
265 QString itemName;
266 if (m_item->isLayout()) {
267 itemName = "layout"_L1;
268 } else {
270 itemName = item->data(0).toString();
271 }
272 }
273 edge.insert(0, "%1_"_L1);
274 return edge.arg(itemName);
275}
276#endif
277
290{
291public:
293
295#ifdef QT_DEBUG
296 QString toString() const;
297#endif
300};
301} // namespace QtGraphicsAnchorLayout
302using namespace QtGraphicsAnchorLayout;
303
305
311{
312 Q_DECLARE_PUBLIC(QGraphicsAnchor)
313
314public:
315 explicit QGraphicsAnchorPrivate(int version = QObjectPrivateVersion);
317
318 void setSpacing(qreal value);
319 void unsetSpacing();
320 qreal spacing() const;
321
323
325 { return q->d_func(); }
326
329
330 // Size information for user controlled anchor
333
334 uint hasSize : 1; // if false, get size from style.
335};
336
337
338
339
346{
347 Q_DECLARE_PUBLIC(QGraphicsAnchorLayout)
348
349public:
350 // When the layout geometry is different from its Minimum, Preferred
351 // or Maximum values, interpolation is used to calculate the geometries
352 // of the items.
353 //
354 // Interval represents which interpolation interval are we operating in.
355 enum Interval {
356 MinimumToMinPreferred = 0,
359 MaxPreferredToMaximum
360 };
361
362 typedef Qt::Orientation Orientation [[deprecated]];
363 [[deprecated]] static inline constexpr Qt::Orientation Horizontal = Qt::Horizontal;
364 [[deprecated]] static inline constexpr Qt::Orientation Vertical = Qt::Vertical;
365
367
369 {
370 return q ? q->d_func() : nullptr;
371 }
372
373 static Qt::AnchorPoint oppositeEdge(
374 Qt::AnchorPoint edge);
375
376 static Qt::Orientation edgeOrientation(Qt::AnchorPoint edge) noexcept;
377
379 {
380 if (orientation == Qt::Vertical && int(edge) <= 2)
381 return (Qt::AnchorPoint)(edge + 3);
382 else if (orientation == Qt::Horizontal && int(edge) >= 3) {
383 return (Qt::AnchorPoint)(edge - 3);
384 }
385 return edge;
386 }
387
388 // Init methods
389 void createLayoutEdges();
390 void deleteLayoutEdges();
391 void createItemEdges(QGraphicsLayoutItem *item);
392 void createCenterAnchors(QGraphicsLayoutItem *item, Qt::AnchorPoint centerEdge);
393 void removeCenterAnchors(QGraphicsLayoutItem *item, Qt::AnchorPoint centerEdge, bool substitute = true);
394 void removeCenterConstraints(QGraphicsLayoutItem *item, Qt::Orientation orientation);
395
397 {
399 if (!data->graphicsAnchor) {
400 data->graphicsAnchor = new QGraphicsAnchor(q);
401 data->graphicsAnchor->d_func()->data = data;
402 }
403 return data->graphicsAnchor;
404 }
405
406 // function used by the 4 API functions
407 QGraphicsAnchor *addAnchor(QGraphicsLayoutItem *firstItem,
408 Qt::AnchorPoint firstEdge,
409 QGraphicsLayoutItem *secondItem,
410 Qt::AnchorPoint secondEdge,
411 qreal *spacing = nullptr);
412
413 // Helper for Anchor Manipulation methods
414 void addAnchor_helper(QGraphicsLayoutItem *firstItem,
415 Qt::AnchorPoint firstEdge,
416 QGraphicsLayoutItem *secondItem,
417 Qt::AnchorPoint secondEdge,
419
420 QGraphicsAnchor *getAnchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge,
421 QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge);
422
423 void removeAnchor(AnchorVertex *firstVertex, AnchorVertex *secondVertex);
424 void removeAnchor_helper(AnchorVertex *v1, AnchorVertex *v2);
425
426 void removeAnchors(QGraphicsLayoutItem *item);
427
428 void removeVertex(QGraphicsLayoutItem *item, Qt::AnchorPoint edge);
429
430 void correctEdgeDirection(QGraphicsLayoutItem *&firstItem,
431 Qt::AnchorPoint &firstEdge,
432 QGraphicsLayoutItem *&secondItem,
433 Qt::AnchorPoint &secondEdge);
434
435 QLayoutStyleInfo &styleInfo() const;
436
437 AnchorData *addAnchorMaybeParallel(AnchorData *newAnchor, bool *feasible);
438
439 // Activation
440 void calculateGraphs();
441 void calculateGraphs(Qt::Orientation orientation);
442
443 // Simplification
444 bool simplifyGraph(Qt::Orientation orientation);
445 bool simplifyVertices(Qt::Orientation orientation);
446 bool simplifyGraphIteration(Qt::Orientation orientation, bool *feasible);
447
448 bool replaceVertex(Qt::Orientation orientation, AnchorVertex *oldV,
449 AnchorVertex *newV, const QList<AnchorData *> &edges);
450
451
452 void restoreSimplifiedGraph(Qt::Orientation orientation);
453 void restoreSimplifiedAnchor(AnchorData *edge);
454 void restoreSimplifiedConstraints(ParallelAnchorData *parallel);
455 void restoreVertices(Qt::Orientation orientation);
456
457 bool calculateTrunk(Qt::Orientation orientation, const GraphPath &trunkPath,
458 const QList<QSimplexConstraint *> &constraints,
459 const QList<AnchorData *> &variables);
460 bool calculateNonTrunk(const QList<QSimplexConstraint *> &constraints,
461 const QList<AnchorData *> &variables);
462
463 // Support functions for calculateGraph()
464 void refreshAllSizeHints(Qt::Orientation orientation);
465 void findPaths(Qt::Orientation orientation);
466 void constraintsFromPaths(Qt::Orientation orientation);
467 void updateAnchorSizes(Qt::Orientation orientation);
468 QList<QSimplexConstraint *> constraintsFromSizeHints(const QList<AnchorData *> &anchors);
469 struct GraphParts {
472 };
473 GraphParts getGraphParts(Qt::Orientation orientation);
474 void identifyFloatItems(const QSet<AnchorData *> &visited, Qt::Orientation orientation);
475 void identifyNonFloatItems_helper(const AnchorData *ad, QSet<QGraphicsLayoutItem *> *nonFloatingItemsIdentifiedSoFar);
476
478 {
479 return m_vertexList.value(itemEdge).first;
480 }
481
483 {
484 return internalVertex(qMakePair(const_cast<QGraphicsLayoutItem *>(item), edge));
485 }
486
487 inline void changeLayoutVertex(Qt::Orientation orientation, AnchorVertex *oldV, AnchorVertex *newV)
488 {
489 if (layoutFirstVertex[orientation] == oldV)
490 layoutFirstVertex[orientation] = newV;
491 else if (layoutCentralVertex[orientation] == oldV)
492 layoutCentralVertex[orientation] = newV;
493 else if (layoutLastVertex[orientation] == oldV)
494 layoutLastVertex[orientation] = newV;
495 }
496
497
498 AnchorVertex *addInternalVertex(QGraphicsLayoutItem *item, Qt::AnchorPoint edge);
499 void removeInternalVertex(QGraphicsLayoutItem *item, Qt::AnchorPoint edge);
500
501 // Geometry interpolation methods
502 void setItemsGeometries(const QRectF &geom);
503
504 void calculateVertexPositions(Qt::Orientation orientation);
505 void setupEdgesInterpolation(Qt::Orientation orientation);
506 void interpolateEdge(AnchorVertex *base, AnchorData *edge);
507
508 // Linear Programming solver methods
509 bool solveMinMax(const QList<QSimplexConstraint *> &constraints,
510 const GraphPath &path, qreal *min, qreal *max);
511 bool solvePreferred(const QList<QSimplexConstraint *> &constraints,
512 const QList<AnchorData *> &variables);
513 bool hasConflicts() const;
514
515#ifdef QT_DEBUG
516 void dumpGraph(const QString &name = QString());
517#endif
518
519
520 QHVContainer<qreal> spacings = {-1, -1};
521 // Size hints from simplex engine
522 QHVContainer<std::array<qreal, 3>> sizeHints = {{-1, -1, -1}, {-1, -1, -1}};
523
524 // Items
526
527 // Mapping between high level anchorage points (Item, Edge) to low level
528 // ones (Graph Vertices)
529
531
532 // Internal graph of anchorage points and anchors, for both orientations
534
535 QHVContainer<AnchorVertex *> layoutFirstVertex = {};
536 QHVContainer<AnchorVertex *> layoutCentralVertex = {};
537 QHVContainer<AnchorVertex *> layoutLastVertex = {};
538
539 // Combined anchors in order of creation
542
543 // Graph paths and constraints, for both orientations
547
548 // The interpolation interval and progress based on the current size
549 // as well as the key values (minimum, preferred and maximum)
551 QHVContainer<qreal> interpolationProgress = {-1, -1};
552
553 QHVContainer<bool> graphHasConflicts = {};
555
556#if defined(QT_DEBUG) || defined(QT_BUILD_INTERNAL)
557 QHVContainer<bool> lastCalculationUsedSimplex;
558#endif
559
561 mutable uint styleInfoDirty : 1;
563
565};
566
568
569#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)
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
Definition qhash.h:818
Definition qlist.h:74
T & first()
Definition qlist.h:628
T & last()
Definition qlist.h:631
const_reference at(qsizetype i) const noexcept
Definition qlist.h:429
\inmodule QtCore\reentrant
Definition qrect.h:483
Definition qset.h:18
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:127
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5710
QString arg(qlonglong a, int fieldwidth=0, int base=10, QChar fillChar=u' ') const
Definition qstring.cpp:8606
QString & insert(qsizetype i, QChar c)
Definition qstring.cpp:3110
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.
Orientation
Definition qnamespace.h:97
@ Horizontal
Definition qnamespace.h:98
@ Vertical
Definition qnamespace.h:99
AnchorPoint
@ AnchorRight
@ AnchorVerticalCenter
@ AnchorBottom
@ AnchorTop
@ AnchorHorizontalCenter
@ AnchorLeft
std::pair< T1, T2 > QPair
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
@ QObjectPrivateVersion
Definition qobject_p.h:61
GLint GLfloat GLfloat GLfloat v2
GLenum type
GLint GLfloat GLfloat v1
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLuint name
GLint first
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLsizei const GLchar *const * path
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)
@ Q_RELOCATABLE_TYPE
Definition qtypeinfo.h:145
#define Q_DECLARE_TYPEINFO(TYPE, FLAGS)
Definition qtypeinfo.h:163
size_t quintptr
Definition qtypes.h:72
unsigned int uint
Definition qtypes.h:29
double qreal
Definition qtypes.h:92
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:24