1
/****************************************************************************
3
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4
** All rights reserved.
5
** Contact: Nokia Corporation (qt-info@nokia.com)
7
** This file is part of the examples of the Qt Toolkit.
9
** You may use this file under the terms of the BSD license as follows:
11
** "Redistribution and use in source and binary forms, with or without
12
** modification, are permitted provided that the following conditions are
14
** * Redistributions of source code must retain the above copyright
15
** notice, this list of conditions and the following disclaimer.
16
** * Redistributions in binary form must reproduce the above copyright
17
** notice, this list of conditions and the following disclaimer in
18
** the documentation and/or other materials provided with the
20
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
21
** the names of its contributors may be used to endorse or promote
22
** products derived from this software without specific prior written
25
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
38
****************************************************************************/
40
#include "qdeclarativelinearlayout.h"
41
#include "qdeclarativelayoutengine_p.h"
42
#include <QtCore/qnumeric.h>
44
static const qreal q_declarativeLayoutDefaultSpacing = 4.0;
47
QDeclarativeLinearLayout::QDeclarativeLinearLayout(Orientation orientation,
48
QDeclarativeItem *parent)
49
: QDeclarativeLayout(parent),
50
m_spacing(q_declarativeLayoutDefaultSpacing),
51
m_orientation(orientation)
56
qreal QDeclarativeLinearLayout::spacing() const
61
void QDeclarativeLinearLayout::setSpacing(qreal spacing)
63
if (qIsNaN(spacing) || m_spacing == spacing)
70
QDeclarativeLinearLayout::Orientation QDeclarativeLinearLayout::orientation() const
75
void QDeclarativeLinearLayout::setOrientation(Orientation orientation)
77
if (m_orientation == orientation)
80
m_orientation = orientation;
83
emit orientationChanged();
86
void QDeclarativeLinearLayout::componentComplete()
88
QDeclarativeLayout::componentComplete();
93
void QDeclarativeLinearLayout::updateLayoutItems()
95
const QList<QGraphicsItem *> &children = childItems();
97
foreach (QGraphicsItem *child, children) {
98
QGraphicsObject *obj = child->toGraphicsObject();
101
QDeclarativeItem *item = qobject_cast<QDeclarativeItem *>(obj);
104
insertLayoutItem(item);
109
QVariant QDeclarativeLinearLayout::itemChange(GraphicsItemChange change, const QVariant &value)
111
if (change == ItemChildAddedChange || change == ItemChildRemovedChange) {
112
QGraphicsItem *child = value.value<QGraphicsItem *>();
113
QGraphicsObject *obj = child ? child->toGraphicsObject() : 0;
114
QDeclarativeItem *item = obj ? qobject_cast<QDeclarativeItem *>(obj) : 0;
117
if (change == ItemChildAddedChange)
118
insertLayoutItem(item);
120
removeLayoutItem(item);
124
return QDeclarativeLayout::itemChange(change, value);
127
void QDeclarativeLinearLayout::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
129
QDeclarativeLayout::geometryChanged(newGeometry, oldGeometry);
133
void QDeclarativeLinearLayout::insertLayoutItem(QDeclarativeItem *item)
135
m_items.append(item);
136
setupItemLayout(item);
139
QObject::connect(item, SIGNAL(destroyed()), this, SLOT(onItemDestroyed()));
142
void QDeclarativeLinearLayout::removeLayoutItem(QDeclarativeItem *item)
144
if (!m_items.removeOne(item))
148
QObject::disconnect(item, SIGNAL(destroyed()), this, SLOT(onItemDestroyed()));
151
void QDeclarativeLinearLayout::onItemDestroyed()
153
if (!m_items.removeOne(static_cast<QDeclarativeItem *>(sender())))
159
void QDeclarativeLinearLayout::reconfigureLayout()
161
if (!isComponentComplete())
164
const int count = m_items.count();
169
qreal totalSpacing = 0;
170
qreal totalSizeHint = 0;
171
qreal totalMinimumSize = 0;
172
qreal totalMaximumSize = 0;
174
QVector<QDeclarativeLayoutInfo> itemData;
176
for (int i = 0; i < count; i++) {
177
QDeclarativeItem *item = m_items.at(i);
178
QObject *attached = qmlAttachedPropertiesObject<QDeclarativeLayout>(item);
179
QDeclarativeLayoutAttached *info = static_cast<QDeclarativeLayoutAttached *>(attached);
181
QDeclarativeLayoutInfo data;
183
if (m_orientation == Horizontal) {
184
data.sizeHint = item->implicitWidth();
185
data.minimumSize = info->minimumWidth();
186
data.maximumSize = info->maximumWidth();
187
data.expansive = (info->horizontalSizePolicy() == QDeclarativeLayout::Expanding);
188
data.stretch = info->horizontalSizePolicy() == Expanding ? 1.0 : 0;
190
data.sizeHint = item->implicitHeight();
191
data.minimumSize = info->minimumHeight();
192
data.maximumSize = info->maximumHeight();
193
data.expansive = (info->verticalSizePolicy() == QDeclarativeLayout::Expanding);
194
data.stretch = info->verticalSizePolicy() == Expanding ? 1.0 : 0;
197
itemData.append(data);
200
totalSizeHint += data.sizeHint;
201
totalMinimumSize += data.minimumSize;
202
totalMaximumSize += data.maximumSize;
204
// don't count last spacing
206
totalSpacing += data.spacing + m_spacing;
209
if (m_orientation == Horizontal) {
210
qDeclarativeLayoutCalculate(itemData, 0, count, 0, width(), m_spacing);
212
for (int i = 0; i < count; i++) {
213
QDeclarativeItem *item = m_items.at(i);
214
const QDeclarativeLayoutInfo &data = itemData.at(i);
216
item->setX(data.pos);
217
item->setY(height()/2 - item->height()/2);
218
item->setWidth(data.size);
221
qDeclarativeLayoutCalculate(itemData, 0, count, 0, height(), m_spacing);
223
for (int i = 0; i < count; i++) {
224
QDeclarativeItem *item = m_items.at(i);
225
const QDeclarativeLayoutInfo &data = itemData.at(i);
227
item->setY(data.pos);
228
item->setX(width()/2 - item->width()/2);
229
item->setHeight(data.size);
233
// propagate hints to upper levels
234
QObject *attached = qmlAttachedPropertiesObject<QDeclarativeLayout>(this);
235
QDeclarativeLayoutAttached *info = static_cast<QDeclarativeLayoutAttached *>(attached);
237
if (m_orientation == Horizontal) {
238
setImplicitWidth(totalSizeHint);
239
info->setMinimumWidth(totalMinimumSize + totalSpacing);
240
info->setMaximumWidth(totalMaximumSize + totalSpacing);
242
setImplicitHeight(totalSizeHint);
243
info->setMinimumHeight(totalMinimumSize + totalSpacing);
244
info->setMaximumHeight(totalMaximumSize + totalSpacing);