source: trunk/src/gui/graphicsview/qgraphicsanchorlayout_p.h@ 1012

Last change on this file since 1012 was 846, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

  • Property svn:eol-style set to native
File size: 19.3 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtGui module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#ifndef QGRAPHICSANCHORLAYOUT_P_H
43#define QGRAPHICSANCHORLAYOUT_P_H
44
45//
46// W A R N I N G
47// -------------
48//
49// This file is not part of the Qt API. It exists purely as an
50// implementation detail. This header file may change from version to
51// version without notice, or even be removed.
52//
53// We mean it.
54//
55
56#include <QGraphicsWidget>
57#include <private/qobject_p.h>
58
59#include "qgraphicslayout_p.h"
60#include "qgraphicsanchorlayout.h"
61#include "qgraph_p.h"
62#include "qsimplex_p.h"
63#ifndef QT_NO_GRAPHICSVIEW
64QT_BEGIN_NAMESPACE
65
66/*
67 The public QGraphicsAnchorLayout interface represents an anchorage point
68 as a pair of a <QGraphicsLayoutItem *> and a <Qt::AnchorPoint>.
69
70 Internally though, it has a graph of anchorage points (vertices) and
71 anchors (edges), represented by the AnchorVertex and AnchorData structs
72 respectively.
73*/
74
75/*!
76 \internal
77
78 Represents a vertex (anchorage point) in the internal graph
79*/
80struct AnchorVertex {
81 enum Type {
82 Normal = 0,
83 Pair
84 };
85
86 AnchorVertex(QGraphicsLayoutItem *item, Qt::AnchorPoint edge)
87 : m_item(item), m_edge(edge), m_type(Normal) {}
88
89 AnchorVertex()
90 : m_item(0), m_edge(Qt::AnchorPoint(0)), m_type(Normal) {}
91
92#ifdef QT_DEBUG
93 inline QString toString() const;
94#endif
95
96 QGraphicsLayoutItem *m_item;
97 Qt::AnchorPoint m_edge;
98 uint m_type : 1;
99
100 // Current distance from this vertex to the layout edge (Left or Top)
101 // Value is calculated from the current anchors sizes.
102 qreal distance;
103};
104
105/*!
106 \internal
107
108 Represents an edge (anchor) in the internal graph.
109*/
110struct AnchorData : public QSimplexVariable {
111 enum Type {
112 Normal = 0,
113 Sequential,
114 Parallel
115 };
116
117 enum Dependency {
118 Independent = 0,
119 Master,
120 Slave
121 };
122
123 AnchorData()
124 : QSimplexVariable(), from(0), to(0),
125 minSize(0), prefSize(0), maxSize(0),
126 minPrefSize(0), maxPrefSize(0),
127 sizeAtMinimum(0), sizeAtPreferred(0),
128 sizeAtMaximum(0), item(0), graphicsAnchor(0),
129 type(Normal), isLayoutAnchor(false),
130 isCenterAnchor(false), orientation(0),
131 dependency(Independent) {}
132 virtual ~AnchorData();
133
134 virtual void updateChildrenSizes() {}
135 void refreshSizeHints(const QLayoutStyleInfo *styleInfo = 0);
136
137#ifdef QT_DEBUG
138 void dump(int indent = 2);
139 inline QString toString() const;
140 QString name;
141#endif
142
143 // Anchor is semantically directed
144 AnchorVertex *from;
145 AnchorVertex *to;
146
147 // Nominal sizes
148 // These are the intrinsic size restrictions for a given item. They are
149 // used as input for the calculation of the actual sizes.
150 // These values are filled by the refreshSizeHints method, based on the
151 // anchor size policy, the size hints of the item it (possibly) represents
152 // and the layout spacing information.
153 qreal minSize;
154 qreal prefSize;
155 qreal maxSize;
156
157 qreal minPrefSize;
158 qreal maxPrefSize;
159
160 // Calculated sizes
161 // These attributes define which sizes should that anchor be in when the
162 // layout is at its minimum, preferred or maximum sizes. Values are
163 // calculated by the Simplex solver based on the current layout setup.
164 qreal sizeAtMinimum;
165 qreal sizeAtPreferred;
166 qreal sizeAtMaximum;
167
168 // References to the classes that represent this anchor in the public world
169 // An anchor may represent a LayoutItem, it may also be acessible externally
170 // through a GraphicsAnchor "handler".
171 QGraphicsLayoutItem *item;
172 QGraphicsAnchor *graphicsAnchor;
173
174 uint type : 2; // either Normal, Sequential or Parallel
175 uint isLayoutAnchor : 1; // if this anchor is an internal layout anchor
176 uint isCenterAnchor : 1;
177 uint orientation : 1;
178 uint dependency : 2; // either Independent, Master or Slave
179};
180
181#ifdef QT_DEBUG
182inline QString AnchorData::toString() const
183{
184 return QString::fromAscii("Anchor(%1)").arg(name);
185}
186#endif
187
188struct SequentialAnchorData : public AnchorData
189{
190 SequentialAnchorData(const QVector<AnchorVertex *> &vertices, const QVector<AnchorData *> &edges)
191 : AnchorData(), m_children(vertices), m_edges(edges)
192 {
193 type = AnchorData::Sequential;
194 orientation = m_edges.at(0)->orientation;
195#ifdef QT_DEBUG
196 name = QString::fromAscii("%1 -- %2").arg(vertices.first()->toString(), vertices.last()->toString());
197#endif
198 }
199
200 virtual void updateChildrenSizes();
201 void calculateSizeHints();
202
203 QVector<AnchorVertex*> m_children; // list of vertices in the sequence
204 QVector<AnchorData*> m_edges; // keep the list of edges too.
205};
206
207struct ParallelAnchorData : public AnchorData
208{
209 ParallelAnchorData(AnchorData *first, AnchorData *second)
210 : AnchorData(), firstEdge(first), secondEdge(second)
211 {
212 type = AnchorData::Parallel;
213 orientation = first->orientation;
214
215 // This assert whether the child anchors share their vertices
216 Q_ASSERT(((first->from == second->from) && (first->to == second->to)) ||
217 ((first->from == second->to) && (first->to == second->from)));
218
219 // Our convention will be that the parallel group anchor will have the same
220 // direction as the first anchor.
221 from = first->from;
222 to = first->to;
223#ifdef QT_DEBUG
224 name = QString::fromAscii("%1 | %2").arg(first->toString(), second->toString());
225#endif
226 }
227
228 virtual void updateChildrenSizes();
229 bool calculateSizeHints();
230
231 bool secondForward() const {
232 // We have the convention that the first children will define the direction of the
233 // pararell group. Note that we can't rely on 'this->from' or 'this->to' because they
234 // might be changed by vertex simplification.
235 return firstEdge->from == secondEdge->from;
236 }
237
238 AnchorData* firstEdge;
239 AnchorData* secondEdge;
240
241 QList<QSimplexConstraint *> m_firstConstraints;
242 QList<QSimplexConstraint *> m_secondConstraints;
243};
244
245struct AnchorVertexPair : public AnchorVertex {
246 AnchorVertexPair(AnchorVertex *v1, AnchorVertex *v2, AnchorData *data)
247 : AnchorVertex(), m_first(v1), m_second(v2), m_removedAnchor(data) {
248 m_type = AnchorVertex::Pair;
249 }
250
251 AnchorVertex *m_first;
252 AnchorVertex *m_second;
253
254 AnchorData *m_removedAnchor;
255 QList<AnchorData *> m_firstAnchors;
256 QList<AnchorData *> m_secondAnchors;
257};
258
259#ifdef QT_DEBUG
260inline QString AnchorVertex::toString() const
261{
262 if (!this) {
263 return QLatin1String("NULL");
264 } else if (m_type == Pair) {
265 const AnchorVertexPair *vp = static_cast<const AnchorVertexPair *>(this);
266 return QString::fromAscii("(%1, %2)").arg(vp->m_first->toString()).arg(vp->m_second->toString());
267 } else if (!m_item) {
268 return QString::fromAscii("NULL_%1").arg(quintptr(this));
269 }
270 QString edge;
271 switch (m_edge) {
272 case Qt::AnchorLeft:
273 edge = QLatin1String("Left");
274 break;
275 case Qt::AnchorHorizontalCenter:
276 edge = QLatin1String("HorizontalCenter");
277 break;
278 case Qt::AnchorRight:
279 edge = QLatin1String("Right");
280 break;
281 case Qt::AnchorTop:
282 edge = QLatin1String("Top");
283 break;
284 case Qt::AnchorVerticalCenter:
285 edge = QLatin1String("VerticalCenter");
286 break;
287 case Qt::AnchorBottom:
288 edge = QLatin1String("Bottom");
289 break;
290 default:
291 edge = QLatin1String("None");
292 break;
293 }
294 QString itemName;
295 if (m_item->isLayout()) {
296 itemName = QLatin1String("layout");
297 } else {
298 if (QGraphicsItem *item = m_item->graphicsItem()) {
299 itemName = item->data(0).toString();
300 }
301 }
302 edge.insert(0, QLatin1String("%1_"));
303 return edge.arg(itemName);
304}
305#endif
306
307/*!
308 \internal
309
310 Representation of a valid path for a given vertex in the graph.
311 In this struct, "positives" is the set of anchors that have been
312 traversed in the forward direction, while "negatives" is the set
313 with the ones walked backwards.
314
315 This paths are compared against each other to produce LP Constraints,
316 the exact order in which the anchors were traversed is not relevant.
317*/
318class GraphPath
319{
320public:
321 GraphPath() {}
322
323 QSimplexConstraint *constraint(const GraphPath &path) const;
324#ifdef QT_DEBUG
325 QString toString() const;
326#endif
327 QSet<AnchorData *> positives;
328 QSet<AnchorData *> negatives;
329};
330
331class QGraphicsAnchorLayoutPrivate;
332/*!
333 \internal
334*/
335class QGraphicsAnchorPrivate : public QObjectPrivate
336{
337 Q_DECLARE_PUBLIC(QGraphicsAnchor)
338
339public:
340 explicit QGraphicsAnchorPrivate(int version = QObjectPrivateVersion);
341 ~QGraphicsAnchorPrivate();
342
343 void setSpacing(qreal value);
344 void unsetSpacing();
345 qreal spacing() const;
346
347 void setSizePolicy(QSizePolicy::Policy policy);
348
349 QGraphicsAnchorLayoutPrivate *layoutPrivate;
350 AnchorData *data;
351
352 // Size information for user controlled anchor
353 QSizePolicy::Policy sizePolicy;
354 qreal preferredSize;
355
356 uint hasSize : 1; // if false, get size from style.
357};
358
359
360
361