6#include <QtWidgets/qwidget.h>
7#include <QtWidgets/qapplication.h>
8#include <QtCore/qstack.h>
11#include <QtCore/qfile.h>
40 data->graphicsAnchor =
nullptr;
57 qWarning(
"QGraphicsAnchor::setSpacing: The anchor does not exist.");
74 qWarning(
"QGraphicsAnchor::setSpacing: The anchor does not exist.");
87 qWarning(
"QGraphicsAnchor::setSpacing: The anchor does not exist.");
114 *minSize = minSizeHint;
116 *minSize = prefSizeHint;
119 *maxSize = maxSizeHint;
121 *maxSize = prefSizeHint;
125 *prefSize = *minSize;
127 *prefSize = prefSizeHint;
194 }
else if (styleInfo) {
338 const qreal lowerBoundary =
340 const qreal upperBoundary =
342 const qreal prefMean =
345 if (lowerBoundary < upperBoundary) {
389 if (
value < minPref) {
393 }
else if (
value < pref) {
397 }
else if (
value < maxPref) {
408 if (upper == lower) {
411 progress = (
value - lower) / (upper - lower);
417static qreal interpolate(
const QPair<QGraphicsAnchorLayoutPrivate::Interval, qreal> &factor,
423 switch (factor.first) {
442 return lower + factor.second * (upper - lower);
450 const QPair<QGraphicsAnchorLayoutPrivate::Interval, qreal> minFactor =
452 const QPair<QGraphicsAnchorLayoutPrivate::Interval, qreal> prefFactor =
454 const QPair<QGraphicsAnchorLayoutPrivate::Interval, qreal> maxFactor =
463 const bool edgeIsForward = (e->from == prev);
465 e->sizeAtMinimum =
interpolate(minFactor, e->minSize, e->minPrefSize,
466 e->prefSize, e->maxPrefSize, e->maxSize);
467 e->sizeAtPreferred =
interpolate(prefFactor, e->minSize, e->minPrefSize,
468 e->prefSize, e->maxPrefSize, e->maxSize);
469 e->sizeAtMaximum =
interpolate(maxFactor, e->minSize, e->minPrefSize,
470 e->prefSize, e->maxPrefSize, e->maxSize);
474 e->sizeAtMinimum =
interpolate(minFactor, e->maxSize, e->maxPrefSize,
475 e->prefSize, e->minPrefSize, e->minSize);
476 e->sizeAtPreferred =
interpolate(prefFactor, e->maxSize, e->maxPrefSize,
477 e->prefSize, e->minPrefSize, e->minSize);
478 e->sizeAtMaximum =
interpolate(maxFactor, e->maxSize, e->maxPrefSize,
479 e->prefSize, e->minPrefSize, e->minSize);
483 e->updateChildrenSizes();
498 const bool edgeIsForward = (edge->from == prev);
524void AnchorData::dump(
int indent) {
526 qDebug(
"%*s type: parallel:", indent,
"");
529 p->secondEdge->dump(indent+2);
532 qDebug(
"%*s type: sequential(%lld):", indent,
"",
qint64(
s->m_edges.size()));
536 qDebug(
"%*s type: Normal:", indent,
"");
545 QSet<AnchorData *> cPositives;
546 QSet<AnchorData *> cNegatives;
547 QSet<AnchorData *> intersection;
552 intersection = cPositives & cNegatives;
554 cPositives -= intersection;
555 cNegatives -= intersection;
560 for (
i = cPositives.begin();
i != cPositives.end(); ++
i)
561 c->variables.insert(*
i, 1.0);
563 for (
i = cNegatives.begin();
i != cNegatives.end(); ++
i)
564 c->variables.insert(*
i, -1.0);
570QString GraphPath::toString()
const
573 string +=
"Path: "_L1;
586 : calculateGraphCacheDirty(true), styleInfoDirty(true)
628 Graph<AnchorVertex, AnchorData> &
g =
graph[orientation];
633 if (
AnchorData *oldAnchor =
g.takeEdge(newAnchor->from, newAnchor->to)) {
643 AnchorData *children[2] = { oldAnchor, newAnchor };
644 QList<QSimplexConstraint *> *childrenConstraints[2] = { ¶llel->m_firstConstraints,
645 ¶llel->m_secondConstraints };
647 for (
int i = 0;
i < 2; ++
i) {
649 QList<QSimplexConstraint *> *childConstraints = childrenConstraints[
i];
656 const bool needsReverse =
i == 1 && !parallel->secondForward();
658 if (!
child->isCenterAnchor)
665 if (
c->variables.contains(
child)) {
666 childConstraints->append(
c);
670 c->variables.insert(parallel,
v);
677 *feasible = parallel->calculateSizeHints();
678 newAnchor = parallel;
681 g.createEdge(newAnchor->from, newAnchor->to, newAnchor);
696 const QList<AnchorVertex *> &vertices,
AnchorVertex *after)
698#if defined(QT_DEBUG) && 0
700 for (
int i = 0;
i < vertices.count(); ++
i) {
708 QList<AnchorData *> edges;
709 edges.reserve(vertices.size() + 1);
711 const int numVertices = vertices.size();
712 edges.reserve(numVertices + 1);
714 for (
int i = 0;
i < numVertices; ++
i) {
723 AnchorData *ad = graph->takeEdge(vertices.last(), after);
729 sequence->
from = before;
730 sequence->
to = after;
779#if defined(QT_DEBUG) && 0
780 qDebug(
"Simplifying Graph for %s",
781 orientation ==
Horizontal ?
"Horizontal" :
"Vertical");
783 static int count = 0;
798 bool feasible =
true;
801 }
while (dirty && feasible);
810#if defined(QT_DEBUG) && 0
821 if (
data->from == oldV) {
834 Graph<AnchorVertex, AnchorData> &
g =
graph[orientation];
835 bool feasible =
true;
837 for (
int i = 0;
i < edges.size(); ++
i) {
842 ad->name =
QString::fromLatin1(
"%1 --to--> %2").arg(ad->from->toString(), ad->to->toString());
847 feasible &= newFeasible;
849 if (newAnchor != ad) {
856 g.takeEdge(oldV, otherV);
868 Graph<AnchorVertex, AnchorData> &
g =
graph[orientation];
871 QStack<AnchorVertex *> stack;
873 QSet<AnchorVertex *> visited;
875 while (!stack.isEmpty()) {
882 QList<AnchorVertex *> adjacents =
g.adjacentVertices(
v);
885 while (
index < adjacents.size()) {
890 const bool bothLayoutVertices =
v->m_item ==
q &&
next->m_item ==
q;
891 const bool zeroSized = !
data->minSize && !
data->maxSize;
893 if (!bothLayoutVertices && zeroSized) {
902 const QList<AnchorVertex *> &vAdjacents =
g.adjacentVertices(
v);
903 const QList<AnchorVertex *> &nextAdjacents =
g.adjacentVertices(
next);
905 for (
int i = 0;
i < vAdjacents.size(); ++
i) {
907 if (adjacent !=
next) {
909 newV->m_firstAnchors.append(ad);
913 for (
int i = 0;
i < nextAdjacents.size(); ++
i) {
917 newV->m_secondAnchors.append(ad);
921 if (!adjacents.contains(adjacent))
922 adjacents.append(adjacent);
928 bool feasible =
replaceVertex(orientation,
v, newV, newV->m_firstAnchors);
935 else if (
next->m_item ==
q)
951 visited.insert(newV);
953 }
else if (!visited.contains(
next) && !stack.contains(
next)) {
982 Graph<AnchorVertex, AnchorData> &
g =
graph[orientation];
984 QSet<AnchorVertex *> visited;
985 QStack<QPair<AnchorVertex *, AnchorVertex *> > stack;
987 QList<AnchorVertex *> candidates;
991 while (!stack.isEmpty()) {
992 QPair<AnchorVertex *, AnchorVertex *> pair = stack.pop();
1006 const QList<AnchorVertex *> &adjacents =
g.adjacentVertices(
v);
1007 const bool isLayoutVertex =
v->
m_item ==
q;
1009 bool endOfSequence =
false;
1016 endOfSequence = isLayoutVertex || adjacents.size() != 2;
1018 if (!endOfSequence) {
1029 if (candidates.isEmpty())
1030 after = (beforeSequence == adjacents.last() ? adjacents.first() : adjacents.last());
1032 after = (candidates.constLast() == adjacents.last() ? adjacents.first() : adjacents.last());
1036 Q_ASSERT(!candidates.contains(after));
1040 const bool cycleFound = visited.contains(after);
1043 endOfSequence = cycleFound ||
data->isCenterAnchor;
1045 if (!endOfSequence) {
1048 candidates.append(
v);
1049 }
else if (cycleFound && (beforeSequence != after)) {
1050 afterSequence = after;
1051 candidates.append(
v);
1058 for (
int i = 0;
i < adjacents.size(); ++
i) {
1060 if (visited.contains(
next))
1075 if (!endOfSequence || candidates.isEmpty())
1084 const AnchorData *firstAnchor =
g.edgeData(beforeSequence, candidates.constFirst());
1085 if (firstAnchor->isCenterAnchor) {
1086 beforeSequence = candidates.constFirst();
1087 candidates.remove(0);
1090 if (candidates.isEmpty())
1094 const AnchorData *lastAnchor =
g.edgeData(candidates.constLast(), afterSequence);
1095 if (lastAnchor->isCenterAnchor) {
1096 afterSequence = candidates.constLast();
1097 candidates.remove(candidates.size() - 1);
1099 if (candidates.isEmpty())
1123 if (newAnchor != sequence)
1138 static const char *anchortypes[] = {
"Normal",
1141 qDebug(
"Restoring %s edge.", anchortypes[
int(edge->
type)]);
1144 Graph<AnchorVertex, AnchorData> &
g =
graph[orientation];
1147 g.createEdge(edge->
from, edge->
to, edge);
1182 if (!parallel->isCenterAnchor)
1185 for (
int i = 0;
i < parallel->m_firstConstraints.size(); ++
i) {
1188 c->variables.
remove(parallel);
1189 c->variables.insert(parallel->firstEdge,
v);
1194 const bool needsReverse = !parallel->secondForward();
1196 for (
int i = 0;
i < parallel->m_secondConstraints.size(); ++
i) {
1201 c->variables.
remove(parallel);
1202 c->variables.insert(parallel->secondEdge,
v);
1209 qDebug(
"Restoring Simplified Graph for %s",
1210 orientation ==
Horizontal ?
"Horizontal" :
"Vertical");
1214 Graph<AnchorVertex, AnchorData> &
g =
graph[orientation];
1215 QList<QPair<AnchorVertex *, AnchorVertex *>> connections =
g.connections();
1216 for (
int i = 0;
i < connections.size(); ++
i) {
1239 Graph<AnchorVertex, AnchorData> &
g =
graph[orientation];
1252 for (
int i = parallelAnchors.size() - 1;
i >= 0; --
i) {
1259 for (
int i = toRestore.size() - 1;
i >= 0; --
i) {
1261 QList<AnchorVertex *> adjacents =
g.adjacentVertices(pair);
1267 g.createEdge(
first, second, pair->m_removedAnchor);
1270 for (
int j = 0;
j < pair->m_firstAnchors.size(); ++
j) {
1272 Q_ASSERT(ad->from == pair || ad->to == pair);
1275 g.createEdge(ad->from, ad->to, ad);
1279 for (
int j = 0;
j < pair->m_secondAnchors.size(); ++
j) {
1281 Q_ASSERT(ad->from == pair || ad->to == pair);
1284 g.createEdge(ad->from, ad->to, ad);
1287 for (
int j = 0;
j < adjacents.size(); ++
j) {
1288 g.takeEdge(pair, adjacents.at(
j));
1293 if (pair->m_item ==
q) {
1302 parallelAnchors.clear();
1370 data->refreshSizeHints();
1374 data->refreshSizeHints();
1394 switch (centerEdge) {
1430 c->variables.insert(
data, 1.0);
1432 data->isCenterAnchor =
true;
1434 data->refreshSizeHints();
1437 c->variables.insert(
data, -1.0);
1439 data->isCenterAnchor =
true;
1441 data->refreshSizeHints();
1460 switch (centerEdge) {
1492 Graph<AnchorVertex, AnchorData> &
g =
graph[orientation];
1508 data->refreshSizeHints();
1517 QList<AnchorVertex*> adjacents =
g.adjacentVertices(center);
1518 for (
int i = 0;
i < adjacents.size(); ++
i) {
1520 if (
v->m_item !=
item) {
1586 if ((firstItem ==
nullptr) || (secondItem ==
nullptr)) {
1587 qWarning(
"QGraphicsAnchorLayout::addAnchor(): "
1588 "Cannot anchor NULL items");
1592 if (firstItem == secondItem) {
1593 qWarning(
"QGraphicsAnchorLayout::addAnchor(): "
1594 "Cannot anchor the item to itself");
1599 qWarning(
"QGraphicsAnchorLayout::addAnchor(): "
1600 "Cannot anchor edges of different orientations");
1605 if (firstItem == parentWidget || secondItem == parentWidget) {
1606 qWarning(
"QGraphicsAnchorLayout::addAnchor(): "
1607 "You cannot add the parent of the layout to the layout.");
1661 return graphicsAnchor;
1688 if (
graph[orientation].edgeData(
v1,
v2)) {
1693 if (firstItem == secondItem)
1694 data->item = firstItem;
1708 data->isLayoutAnchor = (
data->item ==
q);
1719 if (firstItem == secondItem)
1737 graphicsAnchor =
data->graphicsAnchor;
1739 return graphicsAnchor;
1761 firstVertex = secondVertex =
nullptr;
1764 bool keepFirstItem =
false;
1765 bool keepSecondItem =
false;
1767 QPair<AnchorVertex *, int>
v;
1770 if (firstItem !=
q) {
1779 if (
v.second > refcount) {
1780 keepFirstItem =
true;
1786 keepFirstItem =
true;
1788 if (secondItem !=
q) {
1797 if (
v.second > refcount) {
1798 keepSecondItem =
true;
1804 keepSecondItem =
true;
1809 if (!keepSecondItem)
1838 QPair<QGraphicsLayoutItem *, Qt::AnchorPoint> pair(
item, edge);
1859 QPair<QGraphicsLayoutItem *, Qt::AnchorPoint> pair(
item, edge);
1863 qWarning(
"This item with this edge is not in the graph");
1868 if (
v.second == 0) {
1876 if ((
v.second == 2) &&
1888 const auto allVertices =
g.adjacentVertices(
v);
1889 for (
auto *
v2 : allVertices) {
1890 g.removeEdge(
v,
v2);
1940 if ((firstItem !=
q) && (secondItem !=
q)) {
1943 if (firstEdge < secondEdge) {
1944 qSwap(firstItem, secondItem);
1945 qSwap(firstEdge, secondEdge);
1947 }
else if (firstItem ==
q) {
1951 qSwap(firstItem, secondItem);
1952 qSwap(firstEdge, secondEdge);
1957 qSwap(firstItem, secondItem);
1958 qSwap(firstEdge, secondEdge);
2008QList<AnchorData *>
getVariables(
const QList<QSimplexConstraint *> &constraints)
2010 QSet<AnchorData *> variableSet;
2011 for (
int i = 0;
i < constraints.size(); ++
i) {
2014 variableSet.insert(
static_cast<AnchorData *
>(
it.key()));
2016 return variableSet.values();
2044#if defined(QT_DEBUG) || defined(QT_BUILD_INTERNAL)
2045 lastCalculationUsedSimplex[orientation] =
false;
2055 qWarning(
"QGraphicsAnchorLayout: anchor setup is not feasible.");
2082 const QList<AnchorData *> trunkVariables =
getVariables(parts.trunkConstraints);
2089 bool feasible =
calculateTrunk(orientation, trunkPath, parts.trunkConstraints, trunkVariables);
2095 if (feasible && !parts.nonTrunkConstraints.isEmpty()) {
2096 const QList<AnchorData *> partVariables =
getVariables(parts.nonTrunkConstraints);
2097 Q_ASSERT(!partVariables.isEmpty());
2113 if (simplificationEnabled)
2126 for (
int i = 0;
i < constraints.size(); ++
i) {
2128 const qreal multiplier = std::accumulate(
c->variables.cbegin(),
c->variables.cend(),
qreal(0));
2129 c->constant += multiplier * amount;
2140 const QList<QSimplexConstraint *> &constraints,
2141 const QList<AnchorData *> &variables)
2143 bool feasible =
true;
2147 qDebug(
"Simplex %s for trunk of %s", needsSimplex ?
"used" :
"NOT used",
2154 QList<QSimplexConstraint *> allConstraints =
constraints + sizeHintConstraints;
2169 pref += ad->sizeAtPreferred;
2171 pref -= ad->sizeAtPreferred;
2189 ad->sizeAtPreferred = ad->prefSize;
2190 ad->sizeAtMaximum = ad->maxSize;
2197#if defined(QT_DEBUG) || defined(QT_BUILD_INTERNAL)
2198 lastCalculationUsedSimplex[orientation] = needsSimplex;
2208 const QList<AnchorData *> &variables)
2216 for (
int j = 0;
j < variables.size(); ++
j) {
2219 ad->sizeAtMinimum = ad->sizeAtPreferred;
2220 ad->sizeAtMaximum = ad->sizeAtPreferred;
2236 Graph<AnchorVertex, AnchorData> &
g =
graph[orientation];
2237 QList<QPair<AnchorVertex *, AnchorVertex *>> vertices =
g.connections();
2240 for (
int i = 0;
i < vertices.size(); ++
i) {
2258 QQueue<QPair<AnchorVertex *, AnchorVertex *> >
queue;
2260 QSet<AnchorData *> visited;
2266 const auto adjacentVertices =
graph[orientation].adjacentVertices(root);
2270 while(!
queue.isEmpty()) {
2271 QPair<AnchorVertex *, AnchorVertex *> pair =
queue.dequeue();
2272 AnchorData *edge =
graph[orientation].edgeData(pair.first, pair.second);
2274 if (visited.contains(edge))
2277 visited.insert(edge);
2280 if (edge->
from == pair.first)
2285 graphPaths[orientation].insert(pair.second, current);
2287 const auto adjacentVertices =
graph[orientation].adjacentVertices(pair.second);
2310 const auto vertices =
graphPaths[orientation].uniqueKeys();
2312 int valueCount =
graphPaths[orientation].count(vertex);
2313 if (valueCount == 1)
2316 QList<GraphPath> pathsToVertex =
graphPaths[orientation].values(vertex);
2317 for (
int i = 1;
i < valueCount; ++
i) {
2319 pathsToVertex[0].constraint(pathsToVertex.at(
i));
2329 Graph<AnchorVertex, AnchorData> &
g =
graph[orientation];
2330 const QList<QPair<AnchorVertex *, AnchorVertex *>> &vertices =
g.connections();
2332 for (
int i = 0;
i < vertices.size(); ++
i) {
2333 AnchorData *ad =
g.edgeData(vertices.at(
i).first, vertices.at(
i).second);
2345 const QList<AnchorData *> &
anchors)
2348 return QList<QSimplexConstraint *>();
2367 actualMax = layoutEdge->maxSize;
2369 actualMax = -layoutEdge->minSize;
2371 if (actualMax != expectedMax) {
2372 layoutEdge =
nullptr;
2376 QList<QSimplexConstraint *> anchorConstraints;
2377 bool unboundedProblem =
true;
2393 if ((boundedMin == boundedMax) ||
qFuzzyCompare(boundedMin, boundedMax)) {
2396 c->constant = boundedMin;
2398 anchorConstraints +=
c;
2399 unboundedProblem =
false;
2403 c->constant = boundedMin;
2405 anchorConstraints +=
c;
2410 if (ad == layoutEdge)
2415 c->constant = boundedMax;
2417 anchorConstraints +=
c;
2418 unboundedProblem =
false;
2423 if (unboundedProblem) {
2429 anchorConstraints +=
c;
2432 return anchorConstraints;
2459 QSet<QSimplexVariable *> trunkVariables;
2461 trunkVariables += edgeL1;
2463 trunkVariables += edgeL2;
2466 auto end =
result.nonTrunkConstraints.end();
2476 if (
c->variables.contains(ad)) {
2486 for (
auto jt =
c->variables.cbegin(),
end =
c->variables.cend(); jt !=
end; ++jt)
2487 trunkVariables.insert(jt.key());
2501 const auto newEnd = std::remove_if(
result.nonTrunkConstraints.begin(),
end, isMatch);
2502 dirty = newEnd !=
end;
2506 result.nonTrunkConstraints.erase(
end,
result.nonTrunkConstraints.end());
2518 QSet<QGraphicsLayoutItem *> nonFloating;
2523 QSet<QGraphicsLayoutItem *> floatItems;
2525 if (!nonFloating.contains(
item))
2526 floatItems.insert(
item);
2545 if (ad->item && ad->item !=
q)
2546 nonFloatingItemsIdentifiedSoFar->insert(ad->item);
2588 newGeom.setRight(itemPreferredSize.width());
2594 newGeom.setLeft(
left + firstH->distance);
2595 newGeom.setRight(
left + secondH->distance);
2597 newGeom.setLeft(
right - secondH->distance);
2598 newGeom.setRight(
right - firstH->distance);
2604 newGeom.setBottom(itemPreferredSize.height());
2609 newGeom.setTop(
top + firstV->distance);
2610 newGeom.setBottom(
top + secondV->distance);
2613 item->setGeometry(newGeom);
2625 QQueue<QPair<AnchorVertex *, AnchorVertex *> >
queue;
2626 QSet<AnchorVertex *> visited;
2632 visited.insert(root);
2635 const auto adjacentVertices =
graph[orientation].adjacentVertices(root);
2643 while (!
queue.isEmpty()) {
2644 QPair<AnchorVertex *, AnchorVertex *> pair =
queue.dequeue();
2645 AnchorData *edge =
graph[orientation].edgeData(pair.first, pair.second);
2647 if (visited.contains(pair.second))
2650 visited.insert(pair.second);
2653 QList<AnchorVertex *> adjacents =
graph[orientation].adjacentVertices(pair.second);
2654 for (
int i = 0;
i < adjacents.size(); ++
i) {
2655 if (!visited.contains(adjacents.at(
i)))
2674 current = (orientation ==
Qt::Horizontal) ?
q->contentsRect().width() :
q->contentsRect().height();
2676 QPair<Interval, qreal>
result;
2739 simplex.setObjective(&objective);
2742 *min = simplex.solveMin() - objectiveOffset;
2746 for (
int i = 0;
i < variables.size(); ++
i) {
2752 *max = simplex.solveMax() - objectiveOffset;
2755 for (
int i = 0;
i < variables.size(); ++
i) {
2773 limit->constant = interval;
2779 const QList<AnchorData *> &variables)
2781 QList<QSimplexConstraint *> preferredConstraints;
2782 QList<QSimplexVariable *> preferredVariables;
2803 for (
int i = 0;
i < variables.size(); ++
i) {
2807 if (ad->isLayoutAnchor)
2813 preferredConstraints += sizeConstraint;
2818 QPair<QSimplexVariable *, QSimplexConstraint *> slack;
2819 const qreal softShrinkInterval = ad->prefSize - ad->minPrefSize;
2820 if (softShrinkInterval) {
2822 preferredVariables += slack.first;
2823 preferredConstraints += slack.second;
2830 const qreal softGrowInterval = ad->maxPrefSize - ad->prefSize;
2831 if (softGrowInterval) {
2833 preferredVariables += slack.first;
2834 preferredConstraints += slack.second;
2841 const qreal hardShrinkInterval = ad->minPrefSize - ad->minSize;
2842 if (hardShrinkInterval) {
2844 preferredVariables += slack.first;
2845 preferredConstraints += slack.second;
2852 const qreal hardGrowInterval = ad->maxSize - ad->maxPrefSize;
2853 if (hardGrowInterval) {
2855 preferredVariables += slack.first;
2856 preferredConstraints += slack.second;
2866 simplex->setObjective(&objective);
2869 simplex->solveMin();
2872 for (
int i = 0;
i < variables.size(); ++
i) {
2874 ad->sizeAtPreferred = ad->result -
g_offset;
2907void QGraphicsAnchorLayoutPrivate::dumpGraph(
const QString &
name)
static QStyle * style()
Returns the application's style object.
void close() override
Calls QFileDevice::flush() and closes the file.
QFILE_MAYBE_NODISCARD bool open(OpenMode flags) override
Opens the file using OpenMode mode, returning true if successful; otherwise false.
QString fileName() const override
Returns the name set by setFileName() or to the QFile constructors.
bool solvePreferred(const QList< QSimplexConstraint * > &constraints, const QList< AnchorData * > &variables)
QHVContainer< AnchorVertex * > layoutLastVertex
void removeAnchor_helper(AnchorVertex *v1, AnchorVertex *v2)
QList< QSimplexConstraint * > constraintsFromSizeHints(const QList< AnchorData * > &anchors)
bool hasConflicts() const
uint calculateGraphCacheDirty
QHVContainer< Interval > interpolationInterval
QGraphicsAnchor * addAnchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge, qreal *spacing=nullptr)
QHVContainer< Graph< AnchorVertex, AnchorData > > graph
QGraphicsAnchorLayoutPrivate()
QHVContainer< QList< QSimplexConstraint * > > constraints
void setupEdgesInterpolation(Qt::Orientation orientation)
QHVContainer< AnchorVertex * > layoutFirstVertex
QHash< QPair< QGraphicsLayoutItem *, Qt::AnchorPoint >, QPair< AnchorVertex *, int > > m_vertexList
bool replaceVertex(Qt::Orientation orientation, AnchorVertex *oldV, AnchorVertex *newV, const QList< AnchorData * > &edges)
void updateAnchorSizes(Qt::Orientation orientation)
bool calculateNonTrunk(const QList< QSimplexConstraint * > &constraints, const QList< AnchorData * > &variables)
static Qt::AnchorPoint oppositeEdge(Qt::AnchorPoint edge)
bool calculateTrunk(Qt::Orientation orientation, const GraphPath &trunkPath, const QList< QSimplexConstraint * > &constraints, const QList< AnchorData * > &variables)
QHVContainer< QList< AnchorData * > > anchorsFromSimplifiedVertices
bool solveMinMax(const QList< QSimplexConstraint * > &constraints, const GraphPath &path, qreal *min, qreal *max)
QHVContainer< QList< AnchorVertexPair * > > simplifiedVertices
AnchorData * addAnchorMaybeParallel(AnchorData *newAnchor, bool *feasible)
void removeCenterConstraints(QGraphicsLayoutItem *item, Qt::Orientation orientation)
static Qt::AnchorPoint pickEdge(Qt::AnchorPoint edge, Qt::Orientation orientation)
QHVContainer< qreal > spacings
void removeInternalVertex(QGraphicsLayoutItem *item, Qt::AnchorPoint edge)
bool simplifyGraph(Qt::Orientation orientation)
void refreshAllSizeHints(Qt::Orientation orientation)
QHVContainer< QMultiHash< AnchorVertex *, GraphPath > > graphPaths
QHVContainer< bool > graphHasConflicts
static Qt::Orientation edgeOrientation(Qt::AnchorPoint edge) noexcept
void findPaths(Qt::Orientation orientation)
AnchorVertex * addInternalVertex(QGraphicsLayoutItem *item, Qt::AnchorPoint edge)
void createCenterAnchors(QGraphicsLayoutItem *item, Qt::AnchorPoint centerEdge)
QGraphicsAnchor * acquireGraphicsAnchor(AnchorData *data)
QHVContainer< qreal > interpolationProgress
void restoreSimplifiedGraph(Qt::Orientation orientation)
bool simplifyGraphIteration(Qt::Orientation orientation, bool *feasible)
void restoreSimplifiedConstraints(ParallelAnchorData *parallel)
void removeCenterAnchors(QGraphicsLayoutItem *item, Qt::AnchorPoint centerEdge, bool substitute=true)
void calculateVertexPositions(Qt::Orientation orientation)
void changeLayoutVertex(Qt::Orientation orientation, AnchorVertex *oldV, AnchorVertex *newV)
QLayoutStyleInfo cachedStyleInfo
void removeAnchors(QGraphicsLayoutItem *item)
QHVContainer< QList< QSimplexConstraint * > > itemCenterConstraints
static constexpr Qt::Orientation Horizontal
void setItemsGeometries(const QRectF &geom)
@ PreferredToMaxPreferred
@ MinPreferredToPreferred
QHVContainer< QSet< QGraphicsLayoutItem * > > m_floatItems
void removeAnchor(AnchorVertex *firstVertex, AnchorVertex *secondVertex)
QHVContainer< AnchorVertex * > layoutCentralVertex
void restoreVertices(Qt::Orientation orientation)
GraphParts getGraphParts(Qt::Orientation orientation)
QList< QGraphicsLayoutItem * > items
void interpolateEdge(AnchorVertex *base, AnchorData *edge)
void identifyNonFloatItems_helper(const AnchorData *ad, QSet< QGraphicsLayoutItem * > *nonFloatingItemsIdentifiedSoFar)
QGraphicsAnchor * getAnchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge)
bool simplifyVertices(Qt::Orientation orientation)
void restoreSimplifiedAnchor(AnchorData *edge)
void identifyFloatItems(const QSet< AnchorData * > &visited, Qt::Orientation orientation)
AnchorVertex * internalVertex(const QPair< QGraphicsLayoutItem *, Qt::AnchorPoint > &itemEdge) const
void constraintsFromPaths(Qt::Orientation orientation)
QHVContainer< std::array< qreal, 3 > > sizeHints
void correctEdgeDirection(QGraphicsLayoutItem *&firstItem, Qt::AnchorPoint &firstEdge, QGraphicsLayoutItem *&secondItem, Qt::AnchorPoint &secondEdge)
void addAnchor_helper(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge, QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge, AnchorData *data)
QLayoutStyleInfo & styleInfo() const
void removeVertex(QGraphicsLayoutItem *item, Qt::AnchorPoint edge)
void createItemEdges(QGraphicsLayoutItem *item)
The QGraphicsAnchorLayout class provides a layout where one can anchor widgets together in Graphics V...
void setSizePolicy(QSizePolicy::Policy policy)
~QGraphicsAnchorPrivate()
QSizePolicy::Policy sizePolicy
QGraphicsAnchorPrivate(int version=QObjectPrivateVersion)
static QGraphicsAnchorPrivate * get(QGraphicsAnchor *q)
QGraphicsAnchorLayoutPrivate * layoutPrivate
void setSpacing(qreal value)
The QGraphicsAnchor class represents an anchor between two items in a QGraphicsAnchorLayout.
void setSpacing(qreal spacing)
The QGraphicsItem class is the base class for all graphical items in a QGraphicsScene.
QGraphicsLayoutItem * parent
QGraphicsItem * parentItem() const
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.
QSizeF effectiveSizeHint(Qt::SizeHint which, const QSizeF &constraint=QSizeF()) const
Returns the effective size hint for this QGraphicsLayoutItem.
bool isLayout() const
Returns true if this QGraphicsLayoutItem is a layout (e.g., is inherited by an object that arranges o...
QGraphicsLayoutItem * parentLayoutItem() const
Returns the parent of this QGraphicsLayoutItem, or \nullptr if there is no parent,...
QSizePolicy sizePolicy() const
Returns the current size policy.
void addChildLayoutItem(QGraphicsLayoutItem *item)
Qt::LayoutDirection visualDirection() const
bool remove(const Key &key)
Removes the item that has the key from the hash.
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
qint64 write(const char *data, qint64 len)
Writes at most maxSize bytes of data from data to the device.
void setDefaultSpacing(Qt::Orientation o, qreal spacing)
qreal perItemSpacing(QSizePolicy::ControlType control1, QSizePolicy::ControlType control2, Qt::Orientation orientation) const
qreal defaultSpacing(Qt::Orientation o) const
bool isEmpty() const noexcept
void append(parameter_type t)
\inmodule QtCore\reentrant
constexpr qreal left() const noexcept
Returns the x-coordinate of the rectangle's left edge.
constexpr qreal top() const noexcept
Returns the y-coordinate of the rectangle's top edge.
constexpr qreal right() const noexcept
Returns the x-coordinate of the rectangle's right edge.
const_iterator cbegin() const noexcept
bool setConstraints(const QList< QSimplexConstraint * > &constraints)
constexpr qreal width() const noexcept
Returns the width.
constexpr qreal height() const noexcept
Returns the height.
The QSizePolicy class is a layout attribute describing horizontal and vertical resizing policy.
constexpr Policy verticalPolicy() const noexcept
Returns the vertical component of the size policy.
ControlType controlType() const noexcept
constexpr Policy horizontalPolicy() const noexcept
Returns the horizontal component of the size policy.
Policy
This enum describes the various per-dimension sizing types used when constructing a QSizePolicy.
\macro QT_RESTRICTED_CAST_FROM_ASCII
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QString arg(qlonglong a, int fieldwidth=0, int base=10, QChar fillChar=u' ') const
QByteArray toLocal8Bit() const &
The QStyle class is an abstract base class that encapsulates the look and feel of a GUI.
QSet< AnchorData * > negatives
QSet< AnchorData * > positives
QSimplexConstraint * constraint(const GraphPath &path) const
qDeleteAll(list.begin(), list.end())
QSet< QString >::iterator it
Combined button and popup list for selecting options.
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter * iter
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
bool qFuzzyCompare(qfloat16 p1, qfloat16 p2) noexcept
static QPair< QGraphicsAnchorLayoutPrivate::Interval, qreal > getFactor(qreal value, qreal min, qreal minPref, qreal pref, qreal maxPref, qreal max)
static QPair< QSimplexVariable *, QSimplexConstraint * > createSlack(QSimplexConstraint *sizeConstraint, qreal interval, slackType type)
static AnchorData * createSequence(Graph< AnchorVertex, AnchorData > *graph, AnchorVertex *before, const QList< AnchorVertex * > &vertices, AnchorVertex *after)
static qreal interpolate(const QPair< QGraphicsAnchorLayoutPrivate::Interval, qreal > &factor, qreal min, qreal minPref, qreal pref, qreal maxPref, qreal max)
static void applySizePolicy(QSizePolicy::Policy policy, qreal minSizeHint, qreal prefSizeHint, qreal maxSizeHint, qreal *minSize, qreal *prefSize, qreal *maxSize)
static AnchorVertex * replaceVertex_helper(AnchorData *data, AnchorVertex *oldV, AnchorVertex *newV)
static void shiftConstraints(const QList< QSimplexConstraint * > &constraints, qreal amount)
QList< AnchorData * > getVariables(const QList< QSimplexConstraint * > &constraints)
constexpr const T & qMin(const T &a, const T &b)
constexpr const T & qBound(const T &min, const T &val, const T &max)
constexpr const T & qMax(const T &a, const T &b)
static bool contains(const QJsonArray &haystack, unsigned needle)
GLint GLfloat GLfloat GLfloat v2
GLsizei const GLfloat * v
[13]
GLfloat GLfloat GLfloat w
[0]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLdouble GLdouble GLdouble GLdouble top
GLenum GLenum GLsizei count
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLdouble GLdouble GLdouble GLdouble q
GLsizei const GLchar *const * path
GLsizei const GLchar *const * string
[0]
QT_BEGIN_NAMESPACE constexpr decltype(auto) qMakePair(T1 &&value1, T2 &&value2) noexcept(noexcept(std::make_pair(std::forward< T1 >(value1), std::forward< T2 >(value2))))
QQuickAnchors * anchors(QQuickItem *item)
static QString dump(const QByteArray &)
#define qPrintable(string)
#define qUtf16Printable(string)
QT_BEGIN_NAMESPACE constexpr void qSwap(T &value1, T &value2) noexcept(std::is_nothrow_swappable_v< T >)
Q_CORE_EXPORT bool qEnvironmentVariableIsEmpty(const char *varName) noexcept
static bool match(const uchar *found, uint foundLen, const char *target, uint targetLen)
char * toString(const MyType &t)
[31]
qsizetype indexOf(const AT &t, qsizetype from=0) const noexcept
bool contains(const AT &t) const noexcept
QHash< QSimplexVariable *, qreal > variables
virtual void updateChildrenSizes()
void refreshSizeHints(const QLayoutStyleInfo *styleInfo=nullptr)
QGraphicsLayoutItem * item
QGraphicsAnchor * graphicsAnchor
QGraphicsLayoutItem * m_item
virtual void updateChildrenSizes() override
bool calculateSizeHints()
bool secondForward() const
virtual void updateChildrenSizes() override
const QList< AnchorData * > m_edges
void calculateSizeHints()