| 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 | /*!
|
|---|
| 43 | \class QGraphicsAnchorLayout
|
|---|
| 44 | \brief The QGraphicsAnchorLayout class provides a layout where one can anchor widgets
|
|---|
| 45 | together in Graphics View.
|
|---|
| 46 | \since 4.6
|
|---|
| 47 | \ingroup appearance
|
|---|
| 48 | \ingroup geomanagement
|
|---|
| 49 | \ingroup graphicsview-api
|
|---|
| 50 |
|
|---|
| 51 | The anchor layout allows developers to specify how widgets should be placed relative to
|
|---|
| 52 | each other, and to the layout itself. The specification is made by adding anchors to the
|
|---|
| 53 | layout by calling addAnchor(), addAnchors() or addCornerAnchors().
|
|---|
| 54 |
|
|---|
| 55 | Existing anchors in the layout can be accessed with the anchor() function.
|
|---|
| 56 | Items that are anchored are automatically added to the layout, and if items
|
|---|
| 57 | are removed, all their anchors will be automatically removed.
|
|---|
| 58 |
|
|---|
| 59 | \beginfloatleft
|
|---|
| 60 | \inlineimage simpleanchorlayout-example.png Using an anchor layout to align simple colored widgets.
|
|---|
| 61 | \endfloat
|
|---|
| 62 |
|
|---|
| 63 | Anchors are always set up between edges of an item, where the "center" is also considered to
|
|---|
| 64 | be an edge. Consider the following example:
|
|---|
| 65 |
|
|---|
| 66 | \snippet examples/graphicsview/simpleanchorlayout/main.cpp adding anchors
|
|---|
| 67 |
|
|---|
| 68 | Here, the right edge of item \c a is anchored to the left edge of item \c b and the bottom
|
|---|
| 69 | edge of item \c a is anchored to the top edge of item \c b, with the result that
|
|---|
| 70 | item \c b will be placed diagonally to the right and below item \c b.
|
|---|
| 71 |
|
|---|
| 72 | The addCornerAnchors() function provides a simpler way of anchoring the corners
|
|---|
| 73 | of two widgets than the two individual calls to addAnchor() shown in the code
|
|---|
| 74 | above. Here, we see how a widget can be anchored to the top-left corner of the enclosing
|
|---|
| 75 | layout:
|
|---|
| 76 |
|
|---|
| 77 | \snippet examples/graphicsview/simpleanchorlayout/main.cpp adding a corner anchor
|
|---|
| 78 |
|
|---|
| 79 | In cases where anchors are used to match the widths or heights of widgets, it is
|
|---|
| 80 | convenient to use the addAnchors() function. As with the other functions for specifying
|
|---|
| 81 | anchors, it can also be used to anchor a widget to a layout.
|
|---|
| 82 |
|
|---|
| 83 | \clearfloat
|
|---|
| 84 | \section1 Size Hints and Size Policies in an Anchor Layout
|
|---|
| 85 |
|
|---|
| 86 | QGraphicsAnchorLayout respects each item's size hints and size policies.
|
|---|
| 87 | Note that there are some properties of QSizePolicy that are \l{Known issues}{not respected}.
|
|---|
| 88 |
|
|---|
| 89 | \section1 Spacing within an Anchor Layout
|
|---|
| 90 |
|
|---|
| 91 | The layout may distribute some space between the items. If the spacing has not been
|
|---|
| 92 | explicitly specified, the actual amount of space will usually be 0.
|
|---|
| 93 |
|
|---|
| 94 | However, if the first edge is the \e opposite of the second edge (e.g., the right edge
|
|---|
| 95 | of the first widget is anchored to the left edge of the second widget), the size of the
|
|---|
| 96 | anchor will be queried from the style through a pixel metric:
|
|---|
| 97 | \l{QStyle::}{PM_LayoutHorizontalSpacing} for horizontal anchors and
|
|---|
| 98 | \l{QStyle::}{PM_LayoutVerticalSpacing} for vertical anchors.
|
|---|
| 99 |
|
|---|
| 100 | If the spacing is negative, the items will overlap to some extent.
|
|---|
| 101 |
|
|---|
| 102 |
|
|---|
| 103 | \section1 Known issues
|
|---|
| 104 | There are some features that QGraphicsAnchorLayout currently does not support.
|
|---|
| 105 | This might change in the future, so avoid using these features if you want to
|
|---|
| 106 | avoid any future regressions in behaviour:
|
|---|
| 107 | \list
|
|---|
| 108 |
|
|---|
| 109 | \o Stretch factors are not respected.
|
|---|
| 110 |
|
|---|
| 111 | \o QSizePolicy::ExpandFlag is not respected.
|
|---|
| 112 |
|
|---|
| 113 | \o Height for width is not respected.
|
|---|
| 114 |
|
|---|
| 115 | \endlist
|
|---|
| 116 |
|
|---|
| 117 | \sa QGraphicsLinearLayout, QGraphicsGridLayout, QGraphicsLayout
|
|---|
| 118 | */
|
|---|
| 119 |
|
|---|
| 120 | /*!
|
|---|
| 121 | \class QGraphicsAnchor
|
|---|
| 122 | \brief The QGraphicsAnchor class represents an anchor between two items in a
|
|---|
| 123 | QGraphicsAnchorLayout.
|
|---|
| 124 | \since 4.6
|
|---|
| 125 | \ingroup appearance
|
|---|
| 126 | \ingroup geomanagement
|
|---|
| 127 | \ingroup graphicsview-api
|
|---|
| 128 |
|
|---|
| 129 | The graphics anchor provides an API that enables you to query and manipulate the
|
|---|
| 130 | properties an anchor has. When an anchor is added to the layout with
|
|---|
| 131 | QGraphicsAnchorLayout::addAnchor(), a QGraphicsAnchor instance is returned where the properties
|
|---|
| 132 | are initialized to their default values. The properties can then be further changed, and they
|
|---|
| 133 | will be picked up the next time the layout is activated.
|
|---|
| 134 |
|
|---|
| 135 | \sa QGraphicsAnchorLayout::anchor()
|
|---|
| 136 |
|
|---|
| 137 | */
|
|---|
| 138 | #include "qgraphicsanchorlayout_p.h"
|
|---|
| 139 | #ifndef QT_NO_GRAPHICSVIEW
|
|---|
| 140 | QT_BEGIN_NAMESPACE
|
|---|
| 141 |
|
|---|
| 142 | QGraphicsAnchor::QGraphicsAnchor(QGraphicsAnchorLayout *parentLayout)
|
|---|
| 143 | : QObject(*(new QGraphicsAnchorPrivate))
|
|---|
| 144 | {
|
|---|
| 145 | Q_D(QGraphicsAnchor);
|
|---|
| 146 | Q_ASSERT(parentLayout);
|
|---|
| 147 | d->layoutPrivate = parentLayout->d_func();
|
|---|
| 148 | }
|
|---|
| 149 |
|
|---|
| 150 | /*!
|
|---|
| 151 | Removes the QGraphicsAnchor object from the layout and destroys it.
|
|---|
| 152 | */
|
|---|
| 153 | QGraphicsAnchor::~QGraphicsAnchor()
|
|---|
| 154 | {
|
|---|
| 155 | }
|
|---|
| 156 |
|
|---|
| 157 | /*!
|
|---|
| 158 | \property QGraphicsAnchor::sizePolicy
|
|---|
| 159 | \brief the size policy for the QGraphicsAnchor.
|
|---|
| 160 |
|
|---|
| 161 | By setting the size policy on an anchor you can configure how the anchor can resize itself
|
|---|
| 162 | from its preferred spacing. For instance, if the anchor has the size policy
|
|---|
| 163 | QSizePolicy::Minimum, the spacing is the minimum size of the anchor. However, its size
|
|---|
| 164 | can grow up to the anchors maximum size. If the default size policy is QSizePolicy::Fixed,
|
|---|
| 165 | the anchor can neither grow or shrink, which means that the only size the anchor can have
|
|---|
| 166 | is the spacing. QSizePolicy::Fixed is the default size policy.
|
|---|
| 167 | QGraphicsAnchor always has a minimum spacing of 0 and a very large maximum spacing.
|
|---|
| 168 |
|
|---|
| 169 | \sa QGraphicsAnchor::spacing
|
|---|
| 170 | */
|
|---|
| 171 |
|
|---|
| 172 | void QGraphicsAnchor::setSizePolicy(QSizePolicy::Policy policy)
|
|---|
| 173 | {
|
|---|
| 174 | Q_D(QGraphicsAnchor);
|
|---|
| 175 | d->setSizePolicy(policy);
|
|---|
| 176 | }
|
|---|
| 177 |
|
|---|
| 178 | QSizePolicy::Policy QGraphicsAnchor::sizePolicy() const
|
|---|
| 179 | {
|
|---|
| 180 | Q_D(const QGraphicsAnchor);
|
|---|
| 181 | return d->sizePolicy;
|
|---|
| 182 | }
|
|---|
| 183 |
|
|---|
| 184 | /*!
|
|---|
| 185 | \property QGraphicsAnchor::spacing
|
|---|
| 186 | \brief the preferred space between items in the QGraphicsAnchorLayout.
|
|---|
| 187 |
|
|---|
| 188 | Depending on the anchor type, the default spacing is either
|
|---|
| 189 | 0 or a value returned from the style.
|
|---|
| 190 |
|
|---|
| 191 | \sa QGraphicsAnchorLayout::addAnchor()
|
|---|
| 192 | */
|
|---|
| 193 | void QGraphicsAnchor::setSpacing(qreal spacing)
|
|---|
| 194 | {
|
|---|
| 195 | Q_D(QGraphicsAnchor);
|
|---|
| 196 | d->setSpacing(spacing);
|
|---|
| 197 | }
|
|---|
| 198 |
|
|---|
| 199 | qreal QGraphicsAnchor::spacing() const
|
|---|
| 200 | {
|
|---|
| 201 | Q_D(const QGraphicsAnchor);
|
|---|
| 202 | return d->spacing();
|
|---|
| 203 | }
|
|---|
| 204 |
|
|---|
| 205 | void QGraphicsAnchor::unsetSpacing()
|
|---|
| 206 | {
|
|---|
| 207 | Q_D(QGraphicsAnchor);
|
|---|
| 208 | d->unsetSpacing();
|
|---|
| 209 | }
|
|---|
| 210 |
|
|---|
| 211 | /*!
|
|---|
| 212 | Constructs a QGraphicsAnchorLayout instance. \a parent is passed to
|
|---|
| 213 | QGraphicsLayout's constructor.
|
|---|
| 214 | */
|
|---|
| 215 | QGraphicsAnchorLayout::QGraphicsAnchorLayout(QGraphicsLayoutItem *parent)
|
|---|
| 216 | : QGraphicsLayout(*new QGraphicsAnchorLayoutPrivate(), parent)
|
|---|
| 217 | {
|
|---|
| 218 | Q_D(QGraphicsAnchorLayout);
|
|---|
| 219 | d->createLayoutEdges();
|
|---|
| 220 | }
|
|---|
| 221 |
|
|---|
| 222 | /*!
|
|---|
| 223 | Destroys the QGraphicsAnchorLayout object.
|
|---|
| 224 | */
|
|---|
| 225 | QGraphicsAnchorLayout::~QGraphicsAnchorLayout()
|
|---|
| 226 | {
|
|---|
| 227 | Q_D(QGraphicsAnchorLayout);
|
|---|
| 228 |
|
|---|
| 229 | for (int i = count() - 1; i >= 0; --i) {
|
|---|
| 230 | QGraphicsLayoutItem *item = d->items.at(i);
|
|---|
| 231 | removeAt(i);
|
|---|
| 232 | if (item) {
|
|---|
| 233 | if (item->ownedByLayout())
|
|---|
| 234 | delete item;
|
|---|
| 235 | }
|
|---|
| 236 | }
|
|---|
| 237 |
|
|---|
| 238 | d->removeCenterConstraints(this, QGraphicsAnchorLayoutPrivate::Horizontal);
|
|---|
| 239 | d->removeCenterConstraints(this, QGraphicsAnchorLayoutPrivate::Vertical);
|
|---|
| 240 | d->deleteLayoutEdges();
|
|---|
| 241 |
|
|---|
| 242 | Q_ASSERT(d->itemCenterConstraints[0].isEmpty());
|
|---|
| 243 | Q_ASSERT(d->itemCenterConstraints[1].isEmpty());
|
|---|
| 244 | Q_ASSERT(d->items.isEmpty());
|
|---|
| 245 | Q_ASSERT(d->m_vertexList.isEmpty());
|
|---|
| 246 | }
|
|---|
| 247 |
|
|---|
| 248 | /*!
|
|---|
| 249 | Creates an anchor between the edge \a firstEdge of item \a firstItem and the edge \a secondEdge
|
|---|
| 250 | of item \a secondItem. The spacing of the anchor is picked up from the style. Anchors
|
|---|
| 251 | between a layout edge and an item edge will have a size of 0.
|
|---|
| 252 | If there is already an anchor between the edges, the the new anchor will replace the old one.
|
|---|
| 253 |
|
|---|
| 254 | \a firstItem and \a secondItem are automatically added to the layout if they are not part
|
|---|
| 255 | of the layout. This means that count() can increase by up to 2.
|
|---|
| 256 |
|
|---|
| 257 | The spacing an anchor will get depends on the type of anchor. For instance, anchors from the
|
|---|
| 258 | Right edge of one item to the Left edge of another (or vice versa) will use the default
|
|---|
| 259 | horizontal spacing. The same behaviour applies to Bottom to Top anchors, (but they will use
|
|---|
| 260 | the default vertical spacing). For all other anchor combinations, the spacing will be 0.
|
|---|
| 261 | All anchoring functions will follow this rule.
|
|---|
| 262 |
|
|---|
| 263 | The spacing can also be set manually by using QGraphicsAnchor::setSpacing() method.
|
|---|
| 264 |
|
|---|
| 265 | Calling this function where \a firstItem or \a secondItem are ancestors of the layout have
|
|---|
| 266 | undefined behaviour.
|
|---|
| 267 |
|
|---|
| 268 | \sa addAnchors(), addCornerAnchors()
|
|---|
| 269 | */
|
|---|
| 270 | QGraphicsAnchor *
|
|---|
| 271 | QGraphicsAnchorLayout::addAnchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge,
|
|---|
| 272 | QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge)
|
|---|
| 273 | {
|
|---|
| 274 | Q_D(QGraphicsAnchorLayout);
|
|---|
| 275 | QGraphicsAnchor *a = d->addAnchor(firstItem, firstEdge, secondItem, secondEdge);
|
|---|
| 276 | invalidate();
|
|---|
| 277 | return a;
|
|---|
| 278 | }
|
|---|
| 279 |
|
|---|
| 280 | /*!
|
|---|
| 281 | Returns the anchor between the anchor points defined by \a firstItem and \a firstEdge and
|
|---|
| 282 | \a secondItem and \a secondEdge. If there is no such anchor, the function will return 0.
|
|---|
| 283 | */
|
|---|
| 284 | QGraphicsAnchor *
|
|---|
| 285 | QGraphicsAnchorLayout::anchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge,
|
|---|
| 286 | QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge)
|
|---|
| 287 | {
|
|---|
| 288 | Q_D(QGraphicsAnchorLayout);
|
|---|
| 289 | return d->getAnchor(firstItem, firstEdge, secondItem, secondEdge);
|
|---|
| 290 | }
|
|---|
| 291 |
|
|---|
| 292 | /*!
|
|---|
| 293 | Creates two anchors between \a firstItem and \a secondItem specified by the corners,
|
|---|
| 294 | \a firstCorner and \a secondCorner, where one is for the horizontal edge and another
|
|---|
| 295 | one for the vertical edge.
|
|---|
| 296 |
|
|---|
| 297 | This is a convenience function, since anchoring corners can be expressed as anchoring
|
|---|
| 298 | two edges. For instance:
|
|---|
| 299 |
|
|---|
| 300 | \snippet examples/graphicsview/simpleanchorlayout/main.cpp adding a corner anchor in two steps
|
|---|
| 301 |
|
|---|
| 302 | This can also be achieved with the following line of code:
|
|---|
| 303 |
|
|---|
| 304 | \snippet examples/graphicsview/simpleanchorlayout/main.cpp adding a corner anchor
|
|---|
| 305 |
|
|---|
| 306 | If there is already an anchor between the edge pairs, it will be replaced by the anchors that
|
|---|
| 307 | this function specifies.
|
|---|
| 308 |
|
|---|
| 309 | \a firstItem and \a secondItem are automatically added to the layout if they are not part of the
|
|---|
| 310 | layout. This means that count() can increase by up to 2.
|
|---|
| 311 |
|
|---|
| 312 | \sa addAnchor(), addAnchors()
|
|---|
| 313 | */
|
|---|
| 314 | void QGraphicsAnchorLayout::addCornerAnchors(QGraphicsLayoutItem *firstItem,
|
|---|
| 315 | Qt::Corner firstCorner,
|
|---|
| 316 | QGraphicsLayoutItem *secondItem,
|
|---|
| 317 | Qt::Corner secondCorner)
|
|---|
| 318 | {
|
|---|
| 319 | Q_D(QGraphicsAnchorLayout);
|
|---|
| 320 |
|
|---|
| 321 | // Horizontal anchor
|
|---|
| 322 | Qt::AnchorPoint firstEdge = (firstCorner & 1 ? Qt::AnchorRight: Qt::AnchorLeft);
|
|---|
| 323 | Qt::AnchorPoint secondEdge = (secondCorner & 1 ? Qt::AnchorRight: Qt::AnchorLeft);
|
|---|
| 324 | if (d->addAnchor(firstItem, firstEdge, secondItem, secondEdge)) {
|
|---|
| 325 | // Vertical anchor
|
|---|
| 326 | firstEdge = (firstCorner & 2 ? Qt::AnchorBottom: Qt::AnchorTop);
|
|---|
| 327 | secondEdge = (secondCorner & 2 ? Qt::AnchorBottom: Qt::AnchorTop);
|
|---|
| 328 | d->addAnchor(firstItem, firstEdge, secondItem, secondEdge);
|
|---|
| 329 |
|
|---|
| 330 | invalidate();
|
|---|
| 331 | }
|
|---|
| 332 | }
|
|---|
| 333 |
|
|---|
| 334 | /*!
|
|---|
| 335 | Anchors two or four edges of \a firstItem with the corresponding
|
|---|
| 336 | edges of \a secondItem, so that \a firstItem has the same size as
|
|---|
| 337 | \a secondItem in the dimensions specified by \a orientations.
|
|---|
| 338 |
|
|---|
| 339 | For example, the following example anchors the left and right edges of two items
|
|---|
| 340 | to match their widths:
|
|---|
| 341 |
|
|---|
| 342 | \snippet examples/graphicsview/simpleanchorlayout/main.cpp adding anchors to match sizes in two steps
|
|---|
| 343 |
|
|---|
| 344 | This can also be achieved using the following line of code:
|
|---|
| 345 |
|
|---|
| 346 | \snippet examples/graphicsview/simpleanchorlayout/main.cpp adding anchors to match sizes
|
|---|
| 347 |
|
|---|
| 348 | \sa addAnchor(), addCornerAnchors()
|
|---|
| 349 | */
|
|---|
| 350 | void QGraphicsAnchorLayout::addAnchors(QGraphicsLayoutItem *firstItem,
|
|---|
| 351 | QGraphicsLayoutItem *secondItem,
|
|---|
| 352 | Qt::Orientations orientations)
|
|---|
| 353 | {
|
|---|
| 354 | bool ok = true;
|
|---|
| 355 | if (orientations & Qt::Horizontal) {
|
|---|
| 356 | // Currently, if the first is ok, then the rest of the calls should be ok
|
|---|
| 357 | ok = addAnchor(secondItem, Qt::AnchorLeft, firstItem, Qt::AnchorLeft) != 0;
|
|---|
| 358 | if (ok)
|
|---|
| 359 | addAnchor(firstItem, Qt::AnchorRight, secondItem, Qt::AnchorRight);
|
|---|
| 360 | }
|
|---|
| 361 | if (orientations & Qt::Vertical && ok) {
|
|---|
| 362 | addAnchor(secondItem, Qt::AnchorTop, firstItem, Qt::AnchorTop);
|
|---|
| 363 | addAnchor(firstItem, Qt::AnchorBottom, secondItem, Qt::AnchorBottom);
|
|---|
| 364 | }
|
|---|
| 365 | }
|
|---|
| 366 |
|
|---|
| 367 | /*!
|
|---|
| 368 | Sets the default horizontal spacing for the anchor layout to \a spacing.
|
|---|
| 369 |
|
|---|
| 370 | \sa horizontalSpacing(), setVerticalSpacing(), setSpacing()
|
|---|
| 371 | */
|
|---|
| 372 | void QGraphicsAnchorLayout::setHorizontalSpacing(qreal spacing)
|
|---|
| 373 | {
|
|---|
| 374 | Q_D(QGraphicsAnchorLayout);
|
|---|
| 375 |
|
|---|
| 376 | d->spacings[0] = spacing;
|
|---|
| 377 | invalidate();
|
|---|
| 378 | }
|
|---|
| 379 |
|
|---|
| 380 | /*!
|
|---|
| 381 | Sets the default vertical spacing for the anchor layout to \a spacing.
|
|---|
| 382 |
|
|---|
| 383 | \sa verticalSpacing(), setHorizontalSpacing(), setSpacing()
|
|---|
| 384 | */
|
|---|
| 385 | void QGraphicsAnchorLayout::setVerticalSpacing(qreal spacing)
|
|---|
| 386 | {
|
|---|
| 387 | Q_D(QGraphicsAnchorLayout);
|
|---|
| 388 |
|
|---|
| 389 | d->spacings[1] = spacing;
|
|---|
| 390 | invalidate();
|
|---|
| 391 | }
|
|---|
| 392 |
|
|---|
| 393 | /*!
|
|---|
| 394 | Sets the default horizontal and the default vertical spacing for the anchor layout to \a spacing.
|
|---|
| 395 |
|
|---|
| 396 | If an item is anchored with no spacing associated with the anchor, it will use the default
|
|---|
| 397 | spacing.
|
|---|
| 398 |
|
|---|
| 399 | QGraphicsAnchorLayout does not support negative spacings. Setting a negative value will unset the
|
|---|
| 400 | previous spacing and make the layout use the spacing provided by the current widget style.
|
|---|
| 401 |
|
|---|
| 402 | \sa setHorizontalSpacing(), setVerticalSpacing()
|
|---|
| 403 | */
|
|---|
| 404 | void QGraphicsAnchorLayout::setSpacing(qreal spacing)
|
|---|
| 405 | {
|
|---|
| 406 | Q_D(QGraphicsAnchorLayout);
|
|---|
| 407 |
|
|---|
| 408 | d->spacings[0] = d->spacings[1] = spacing;
|
|---|
| 409 | invalidate();
|
|---|
| 410 | }
|
|---|
| 411 |
|
|---|
| 412 | /*!
|
|---|
| 413 | Returns the default horizontal spacing for the anchor layout.
|
|---|
| 414 |
|
|---|
| 415 | \sa verticalSpacing(), setHorizontalSpacing()
|
|---|
| 416 | */
|
|---|
| 417 | qreal QGraphicsAnchorLayout::horizontalSpacing() const
|
|---|
| 418 | {
|
|---|
| 419 | Q_D(const QGraphicsAnchorLayout);
|
|---|
| 420 | return d->styleInfo().defaultSpacing(Qt::Horizontal);
|
|---|
| 421 | }
|
|---|
| 422 |
|
|---|
| 423 | /*!
|
|---|
| 424 | Returns the default vertical spacing for the anchor layout.
|
|---|
| 425 |
|
|---|
| 426 | \sa horizontalSpacing(), setVerticalSpacing()
|
|---|
| 427 | */
|
|---|
| 428 | qreal QGraphicsAnchorLayout::verticalSpacing() const
|
|---|
| 429 | {
|
|---|
| 430 | Q_D(const QGraphicsAnchorLayout);
|
|---|
| 431 | return d->styleInfo().defaultSpacing(Qt::Vertical);
|
|---|
| 432 | }
|
|---|
| 433 |
|
|---|
| 434 | /*!
|
|---|
| 435 | \reimp
|
|---|
| 436 | */
|
|---|
| 437 | void QGraphicsAnchorLayout::setGeometry(const QRectF &geom)
|
|---|
| 438 | {
|
|---|
| 439 | Q_D(QGraphicsAnchorLayout);
|
|---|
| 440 |
|
|---|
| 441 | QGraphicsLayout::setGeometry(geom);
|
|---|
| 442 | d->calculateVertexPositions(QGraphicsAnchorLayoutPrivate::Horizontal);
|
|---|
| 443 | d->calculateVertexPositions(QGraphicsAnchorLayoutPrivate::Vertical);
|
|---|
| 444 | d->setItemsGeometries(geom);
|
|---|
| 445 | }
|
|---|
| 446 |
|
|---|
| 447 | /*!
|
|---|
| 448 | Removes the layout item at \a index without destroying it. Ownership of
|
|---|
| 449 | the item is transferred to the caller.
|
|---|
| 450 |
|
|---|
| 451 | Removing an item will also remove any of the anchors associated with it.
|
|---|
| 452 |
|
|---|
| 453 | \sa itemAt(), count()
|
|---|
| 454 | */
|
|---|
| 455 | void QGraphicsAnchorLayout::removeAt(int index)
|
|---|
| 456 | {
|
|---|
| 457 | Q_D(QGraphicsAnchorLayout);
|
|---|
| 458 | QGraphicsLayoutItem *item = d->items.value(index);
|
|---|
| 459 |
|
|---|
| 460 | if (!item)
|
|---|
| 461 | return;
|
|---|
| 462 |
|
|---|
| 463 | // Removing an item affects both horizontal and vertical graphs
|
|---|
| 464 | d->removeCenterConstraints(item, QGraphicsAnchorLayoutPrivate::Horizontal);
|
|---|
| 465 | d->removeCenterConstraints(item, QGraphicsAnchorLayoutPrivate::Vertical);
|
|---|
| 466 | d->removeAnchors(item);
|
|---|
| 467 | d->items.remove(index);
|
|---|
| 468 |
|
|---|
| 469 | item->setParentLayoutItem(0);
|
|---|
| 470 | invalidate();
|
|---|
| 471 | }
|
|---|
| 472 |
|
|---|
| 473 | /*!
|
|---|
| 474 | \reimp
|
|---|
| 475 | */
|
|---|
| 476 | int QGraphicsAnchorLayout::count() const
|
|---|
| 477 | {
|
|---|
| 478 | Q_D(const QGraphicsAnchorLayout);
|
|---|
| 479 | return d->items.size();
|
|---|
| 480 | }
|
|---|
| 481 |
|
|---|
| 482 | /*!
|
|---|
| 483 | \reimp
|
|---|
| 484 | */
|
|---|
| 485 | QGraphicsLayoutItem *QGraphicsAnchorLayout::itemAt(int index) const
|
|---|
| 486 | {
|
|---|
| 487 | Q_D(const QGraphicsAnchorLayout);
|
|---|
| 488 | return d->items.value(index);
|
|---|
| 489 | }
|
|---|
| 490 |
|
|---|
| 491 | /*!
|
|---|
| 492 | \reimp
|
|---|
| 493 | */
|
|---|
| 494 | void QGraphicsAnchorLayout::invalidate()
|
|---|
| 495 | {
|
|---|
| 496 | Q_D(QGraphicsAnchorLayout);
|
|---|
| 497 | QGraphicsLayout::invalidate();
|
|---|
| 498 | d->calculateGraphCacheDirty = true;
|
|---|
| 499 | d->styleInfoDirty = true;
|
|---|
| 500 | }
|
|---|
| 501 |
|
|---|
| 502 | /*!
|
|---|
| 503 | \reimp
|
|---|
| 504 | */
|
|---|
| 505 | QSizeF QGraphicsAnchorLayout::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
|
|---|
| 506 | {
|
|---|
| 507 | Q_UNUSED(constraint);
|
|---|
| 508 | Q_D(const QGraphicsAnchorLayout);
|
|---|
| 509 |
|
|---|
| 510 | // Some setup calculations are delayed until the information is
|
|---|
| 511 | // actually needed, avoiding unnecessary recalculations when
|
|---|
| 512 | // adding multiple anchors.
|
|---|
| 513 |
|
|---|
| 514 | // sizeHint() / effectiveSizeHint() already have a cache
|
|---|
| 515 | // mechanism, using invalidate() to force recalculation. However
|
|---|
| 516 | // sizeHint() is called three times after invalidation (for max,
|
|---|
| 517 | // min and pref), but we just need do our setup once.
|
|---|
| 518 |
|
|---|
| 519 | const_cast<QGraphicsAnchorLayoutPrivate *>(d)->calculateGraphs();
|
|---|
| 520 |
|
|---|
| 521 | // ### apply constraint!
|
|---|
| 522 | QSizeF engineSizeHint(
|
|---|
| 523 | d->sizeHints[QGraphicsAnchorLayoutPrivate::Horizontal][which],
|
|---|
| 524 | d->sizeHints[QGraphicsAnchorLayoutPrivate::Vertical][which]);
|
|---|
| 525 |
|
|---|
| 526 | qreal left, top, right, bottom;
|
|---|
| 527 | getContentsMargins(&left, &top, &right, &bottom);
|
|---|
| 528 |
|
|---|
| 529 | return engineSizeHint + QSizeF(left + right, top + bottom);
|
|---|
| 530 | }
|
|---|
| 531 |
|
|---|
| 532 | QT_END_NAMESPACE
|
|---|
| 533 | #endif //QT_NO_GRAPHICSVIEW
|
|---|