src/hbcore/layouts/hbstackedlayout.cpp
changeset 0 16d8024aca5e
child 5 627c4a0fd0e7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hbcore/layouts/hbstackedlayout.cpp	Mon Apr 19 14:02:13 2010 +0300
@@ -0,0 +1,300 @@
+/****************************************************************************
+**
+** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (developer.feedback@nokia.com)
+**
+** This file is part of the HbCore module of the UI Extensions for Mobile.
+**
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at developer.feedback@nokia.com.
+**
+****************************************************************************/
+
+#include "hbstackedlayout.h"
+#include "hbapplication.h"
+#include "hbinstance.h"
+#include "hblayoututils_p.h"
+
+#include <QList>
+#include <QGraphicsLayoutItem>
+#include <QGraphicsWidget>
+#include <QWidget> // for QWIDGETSIZE_MAX
+
+/*!
+    @stable
+    @hbcore
+    \class HbStackedLayout
+    \brief HbStackedLayout manages geometries of stacked layout contents.
+
+    HbStackedLayout is a simple stack layout manager. It will only set position
+    and size for the contained child widget.
+
+    Example code:
+    \snippet{stackedlayoutsample.cpp,1}
+
+    \sa HbStackedWidget
+ */
+
+class HbStackedLayoutPrivate
+{
+public:
+    HbStackedLayoutPrivate();
+    QList<QGraphicsLayoutItem *> mList;
+};
+
+/*!
+    \internal
+ */
+HbStackedLayoutPrivate::HbStackedLayoutPrivate()
+{
+}
+
+/*!
+    Constructor.
+    \param parent parent layout item.
+ */
+HbStackedLayout::HbStackedLayout(QGraphicsLayoutItem * parent)
+    : QGraphicsLayout(parent), d(new HbStackedLayoutPrivate())
+{
+}
+
+/*!
+    Destructor.
+    Does not clear the parentLayoutItem of it's sub items.
+    If you want to reuse the sub items first call removeAt()
+    for each of them.
+ */
+HbStackedLayout::~HbStackedLayout()
+{
+    if (d) {
+        for (int i = count() - 1; i >= 0; --i) {
+            QGraphicsLayoutItem *item = itemAt(i);
+            // The following lines can be removed, but this removes the item
+            // from the layout more efficiently than the implementation of 
+            // ~QGraphicsLayoutItem.
+            removeAt(i);
+            if (item) {
+                item->setParentLayoutItem(0);
+                if (item->ownedByLayout()) {
+                    delete item;
+                }
+            }
+        }
+    }
+    
+    delete d;
+}
+
+/*!
+    \brief Appends a layout item to the stacked layout.
+
+    This is convenience function which will internally call the \c insertItem method.
+
+    \param item layout item to be added to stack.
+    \return index to which layout item was added.
+ */
+int HbStackedLayout::addItem(QGraphicsLayoutItem *item)
+{
+    return insertItem(-1, item);
+}
+
+/*!
+    \brief  Inserts a layout item to the stacked layout.
+
+    Inserts the given \a item to given position \a index.
+
+    Also reparents \a item to the parent item of this layout, if there
+    is one.
+
+    If index is out of range, the item is appended (in which case it
+    is the actual index of the item that is returned).
+
+    \param  index position where to insert the layout.
+    \param  item layout item to be inserted to stack.
+    \return index to which layout item was added.
+ */
+int HbStackedLayout::insertItem(int index, QGraphicsLayoutItem *item)
+{
+    if( !item ) {
+        qWarning("HbStackedLayout::insertItem: item is NULL");
+        return -1;
+    }
+
+    if (item->parentLayoutItem()) {
+        qWarning("HbStackedLayout::insertItem: layout already has a parent");
+        return -1;
+    }
+
+    HbLayoutUtils::addChildItem(this, item);
+
+    index = qMin(index, d->mList.count());
+    if (index < 0) {
+        index = d->mList.count();
+    }
+    d->mList.insert(index, item);
+
+    invalidate();
+    return index;
+}
+
+/*!
+    \brief Removes layout item from the stacked layout.
+
+    This method will internally call \c removeAt.
+
+    \param item item to be removed.
+    \sa removeAt
+ */
+void HbStackedLayout::removeItem(QGraphicsLayoutItem *item)
+{
+    removeAt( indexOf( item ) );
+}
+
+/*!
+    \brief Returns position of layout item in the stacked layout.
+    \return position of layout item, or -1 if not found.
+ */
+int HbStackedLayout::indexOf(QGraphicsLayoutItem *item) const
+{
+    int c = d->mList.count();
+    for ( int i = 0; i < c; i++ ) {
+        if ( d->mList.at(i) == item ) {
+            return i;
+        }
+    }
+    return -1;
+}
+
+/*!
+    From QGraphicsLayout.
+ */
+int HbStackedLayout::count() const
+{
+    return d->mList.size();
+}
+
+/*!
+    From QGraphicsLayout.
+ */
+QGraphicsLayoutItem *HbStackedLayout::itemAt(int index) const
+{
+    return d->mList.value(index);
+}
+
+/*!
+    From QGraphicsLayout.
+    Clears the parentLayoutItem of removed item.
+ */
+void HbStackedLayout::removeAt(int index)
+{
+    if (index <0 || index >= d->mList.size()) {
+        return;
+    }
+    itemAt(index)->setParentLayoutItem(0);
+    d->mList.removeAt(index);
+    invalidate();
+}
+
+/*!
+    From QGraphicsLayout.
+ */
+void HbStackedLayout::invalidate()
+{
+    QGraphicsLayout::invalidate();
+}
+
+/*!
+    From QGraphicsLayout.
+
+    The minimum size hint is the maximum of the minimum size hints of the
+    child layout items plus content margins.
+
+    The preferred size hint is the maximum of the preferred size hints of the
+    child layout items plus content margins.
+
+    The maximum size hint "unlimited", i.e. the child layout items do not
+    affect the maximum size hint.
+ */
+QSizeF HbStackedLayout::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
+{
+    if (which == Qt::MaximumSize) {
+        // Sub items do not affect the maximum size hint.
+        return QSizeF( QWIDGETSIZE_MAX, QWIDGETSIZE_MAX );
+    }
+    QSizeF sizeHint(0, 0);
+    int c = d->mList.count();
+    for ( int i=0; i < c; ++i ) {
+        QGraphicsLayoutItem* item = d->mList.at(i);
+        QSizeF itemSize(item->effectiveSizeHint(which, constraint));
+        if (item->sizePolicy().horizontalPolicy() == QSizePolicy::Ignored) {
+            itemSize.setWidth(0);
+        }
+        if (item->sizePolicy().verticalPolicy() == QSizePolicy::Ignored) {
+            itemSize.setHeight(0);
+        }
+        if ( itemSize.isValid() ) {
+            sizeHint = sizeHint.expandedTo(itemSize);
+        }
+    }
+    // Apply margins
+    qreal left, top, right, bottom;
+    getContentsMargins(&left, &top, &right, &bottom);
+    sizeHint.rheight() += top + bottom;
+    sizeHint.rwidth() += left + right;
+    return sizeHint;
+}
+
+/*!
+    From QGraphicsLayout.
+ */
+void HbStackedLayout::setGeometry(const QRectF &rect)
+{
+    QGraphicsLayout::setGeometry(rect);
+
+    int c = d->mList.count();
+    for ( int i=0; i < c; ++i ) {
+        QGraphicsLayoutItem* item = d->mList.at(i);
+        QSizeF itemMax = item->effectiveSizeHint(Qt::MaximumSize);
+        QSizeF itemMin = item->effectiveSizeHint(Qt::MinimumSize);
+        QRectF itemRect(rect);
+        // Have to check min and max "manually" in order
+        // to make mirroring work.
+        if ( itemMax.width() < itemRect.width() ) {
+            itemRect.setWidth( itemMax.width() );
+        }
+        if ( itemMax.height() < itemRect.height() ) {
+            itemRect.setHeight( itemMax.height() );
+        }
+        if ( itemMin.width() > itemRect.width() ) {
+            itemRect.setWidth( itemMin.width() );
+        }
+        if ( itemMin.height() > itemRect.height() ) {
+            itemRect.setHeight( itemMin.height() );
+        }
+        alignRect(itemRect, rect);
+        item->setGeometry(itemRect);
+    }
+}
+
+/*!
+    \internal
+ */
+void HbStackedLayout::alignRect( QRectF &rect, const QRectF &boundingRect )
+{
+    if (HbApplication::layoutDirection() == Qt::RightToLeft) {
+        rect.moveLeft( 2 * boundingRect.x() + boundingRect.width() - rect.x() - rect.width() );
+    }
+}