--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hbcore/gui/hbstackedwidget.cpp Mon Apr 19 14:02:13 2010 +0300
@@ -0,0 +1,368 @@
+/****************************************************************************
+**
+** 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 "hbstackedwidget.h"
+#include "hbstackedlayout.h"
+#include "hbwidget_p.h"
+
+/*!
+ \class HbStackedWidget
+ \brief HbStackedWidget manages geometries of stacked layout contents.
+
+ HbStackedLayout is a simple container that allows client add several widgets
+ and then select one widget to be shown. This widget will manage visibility
+ and focus in addition to size and position.
+
+ Example code:
+ \snippet{stackedwidgetsample.cpp,1}
+
+ \sa HbStackedLayout
+ \alpha
+ */
+
+
+class HbStackedWidgetPrivate : public HbWidgetPrivate
+{
+ Q_DECLARE_PUBLIC(HbStackedWidget)
+
+public:
+ HbStackedWidgetPrivate() : mCurrentIndex(-1), mLayout(0) {}
+
+ void setCurrentIndex(int index, QGraphicsWidget *prev, bool hideOld = true, bool showNew = true);
+
+ int mCurrentIndex;
+ HbStackedLayout *mLayout;
+};
+
+/*!
+ \brief Sets current widget from specified index.
+ \param index position of desired widget.
+ \param prev previous widget.
+ */
+void HbStackedWidgetPrivate::setCurrentIndex(int index, QGraphicsWidget *prev, bool hideOld, bool showNew)
+{
+ Q_Q(HbStackedWidget);
+ if (index < 0 || index >= mLayout->count()) {
+ qWarning("HbStackedWidget::setCurrentIndex: index %i is out of range", index);
+ return;
+ }
+
+ QGraphicsWidget *next = q->widgetAt(index);
+ if (next == prev)
+ return;
+
+ QGraphicsWidget* focused = 0;
+ if (prev) {
+ focused = prev->focusWidget();
+ // Set previous widget invisible. Focus will be reset after this statement.
+ if (hideOld) {
+ prev->setVisible(false);
+ }
+ }
+ mCurrentIndex = index;
+ if (showNew) {
+ next->setVisible(true);
+ }
+
+ // set the focus if prev was focusable
+ if (focused) {
+ next->setFocus();
+ }
+ emit q->currentChanged(index);
+}
+
+/*!
+ Constructor.
+ \param parent parent graphics item
+ */
+HbStackedWidget::HbStackedWidget(QGraphicsItem *parent)
+ : HbWidget(*new HbStackedWidgetPrivate, parent)
+{
+ Q_D(HbStackedWidget);
+ d->q_ptr = this;
+
+ HbStackedLayout *layout = new HbStackedLayout;
+ setLayout( layout );
+ d->mLayout = layout;
+}
+
+/*!
+ Destructor
+ */
+HbStackedWidget::~HbStackedWidget()
+{
+}
+
+/*!
+ \brief Returns amount of widgets.
+ \return amount of widgets.
+ */
+int HbStackedWidget::count() const
+{
+ Q_D(const HbStackedWidget);
+ return d->mLayout->count();
+}
+
+/*!
+ \brief Adds a widget.
+
+ This is a convenience function which will internally call the \c insertWidget method.
+
+ \param widget widget to be added.
+ \return index of the added widget in the stack.
+ */
+int HbStackedWidget::addWidget(QGraphicsWidget *widget)
+{
+ return insertWidget(-1, widget);
+}
+
+/*!
+ \brief Inserts a widget.
+
+ Inserts the given \a widget to given position \a index.
+ Takes ownership of the widget.
+
+ If \a index is out of range, the widget is appended (in which case it is the actual
+ index of the widget that is returned).
+
+ If the stack was empty before this function is called, the given widget becomes
+ the current widget and it will be set visible. Otherwise the widget will be set
+ invisible.
+
+ Inserting a new widget at an index less than or equal to the current index will increment
+ the current index, but keep the current widget.
+
+ \param index index to which to add.
+ \param widget widget to be inserted.
+ \return index of the added widget in the stack.
+ */
+int HbStackedWidget::insertWidget(int index, QGraphicsWidget *widget)
+{
+ Q_D(HbStackedWidget);
+ int addedIndex = d->mLayout->insertItem(index, widget); // this will usually reparent 'widget'
+ if ( addedIndex != -1 ) {
+ // Need to store current index, since it might change
+ // during "widgetAdded" signal (someone might call back
+ // e.g. "setCurrentIndex".
+ int currentIndex = d->mCurrentIndex;
+ emit widgetAdded(addedIndex);
+ if ( currentIndex == d->mCurrentIndex ) {
+ // Current index not touched from outside.
+ if (d->mCurrentIndex < 0) {
+ setCurrentIndex(addedIndex);
+ } else {
+ widget->setVisible(false);
+ if (addedIndex <= d->mCurrentIndex) {
+ d->mCurrentIndex++;
+ emit currentChanged(d->mCurrentIndex);
+ }
+ }
+ }
+ }
+ return addedIndex;
+}
+
+/*!
+ \brief Removes a widget.
+
+ Removes the given \a widget from the stack. The widget is not deleted.
+ The widget is set invisible.
+
+ Removing the current widget will set the next widget (or previous
+ if the current widget was the last one) to be the current widget.
+
+ Removing a widget from an index less than the current index will
+ decrement the current index, but keep the current widget.
+
+ \param widget widget to be removed.
+ */
+void HbStackedWidget::removeWidget(QGraphicsWidget *widget)
+{
+ Q_D(HbStackedWidget);
+ int index = indexOf(widget);
+ if ( index == -1 ) {
+ return;
+ }
+ d->mLayout->removeAt(index);
+
+ if ( index == d->mCurrentIndex ) {
+ d->mCurrentIndex = -1;
+ int c = count();
+ if ( c > 0 ) {
+ int newIndex = (index == c) ? index-1 : index;
+ d->setCurrentIndex(newIndex, widget);
+ } else {
+ // The last widget was removed.
+ widget->setVisible(false);
+ emit currentChanged( -1 );
+ }
+ } else if ( index <= d->mCurrentIndex ) {
+ d->mCurrentIndex--;
+ emit currentChanged(d->mCurrentIndex);
+ }
+ widget->setParentItem(0);
+ emit widgetRemoved(index);
+ emit widgetRemoved(widget);
+}
+
+/*!
+ \brief Removes a widget from specified position.
+
+ This is a convenience function which will internally call the \c removeWidget method.
+
+ The removed widget is not deleted but returned to caller.
+
+ \param index position of the widget to be removed.
+ \return the removed widget.
+ */
+QGraphicsWidget *HbStackedWidget::removeAt(int index)
+{
+ QGraphicsWidget *widget = widgetAt(index);
+ if ( widget ) {
+ removeWidget(widget);
+ }
+ return widget;
+}
+
+
+/*!
+ \brief Returns position of specified widget.
+ \param widget widget to look for.
+ */
+int HbStackedWidget::indexOf(QGraphicsWidget *widget) const
+{
+ Q_D(const HbStackedWidget);
+ return d->mLayout->indexOf(widget);
+}
+
+/*!
+ \brief Returns index of current widget.
+ \return current index, or -1 if undefined.
+ */
+int HbStackedWidget::currentIndex() const
+{
+ Q_D(const HbStackedWidget);
+ return d->mCurrentIndex;
+}
+
+/*!
+ \brief Returns widget at specified position.
+ \param index position of widget.
+ */
+QGraphicsWidget *HbStackedWidget::widgetAt(int index) const
+{
+ Q_D(const HbStackedWidget);
+ return static_cast<QGraphicsWidget*>(d->mLayout->itemAt(index));
+}
+
+/*!
+ \brief Returns current widget.
+ \return current widget, or 0 if undefined.
+ */
+QGraphicsWidget *HbStackedWidget::currentWidget() const
+{
+ Q_D(const HbStackedWidget);
+ return widgetAt(d->mCurrentIndex);
+}
+
+/*! \fn void HbStackedWidget::widgetAdded(int index)
+ \brief This signal is emitted when a widget is added to this widget.
+ \param index position of the added widget.
+ */
+
+/*! \fn void HbStackedWidget::widgetRemoved(int index)
+ \brief This signal is emitted when a widget is removed from this widget.
+ \param index position of the removed widget.
+ */
+
+/*! \fn void HbStackedWidget::widgetRemoved(QGraphicsWidget *widget)
+ \brief This signal is emitted when a widget is removed from this widget.
+ \param widget the removed widget.
+ */
+
+/*! \fn void HbStackedWidget::currentChanged(int index)
+ \brief This signal is emitted when the current widget is changed.
+
+ The signal is emitted whenever either the current index or the current
+ widget changes. In some cases (e.g. when removing a widget before the
+ current widget) the current index changes but current widget doesn't and
+ in some other cases (e.g. when removing the current widget) the current
+ widget changes but the current index doesn't.
+
+ \param index position of the new current widget.
+ */
+
+ /*!
+ \brief Sets current widget from specified index.
+
+ This method will set the widget at given \a index visible and
+ the previous widget invisible.
+
+ \param index position of desired widget.
+ */
+void HbStackedWidget::setCurrentIndex(int index)
+{
+ Q_D(HbStackedWidget);
+ d->setCurrentIndex(index, currentWidget());
+}
+
+/*!
+ \brief Sets current widget.
+
+ This is a convenience function, same as finding the widget's index
+ and calling setCurrentIndex().
+
+ \param widget desired widget.
+ */
+void HbStackedWidget::setCurrentWidget(QGraphicsWidget *widget)
+{
+ Q_D(HbStackedWidget);
+ int index = d->mLayout->indexOf(widget);
+ if (index == -1) {
+ qWarning("HbStackedWidget::setCurrentWidget: Widget %p not contained in stack", widget);
+ return;
+ }
+ d->setCurrentIndex(index, currentWidget());
+}
+
+/*!
+ \brief Sets current widget.
+
+ This is a convenience function which will internally call the \c setCurrentIndex method.
+
+ \param widget Desired widget.
+ \param hideOld Indicates of the old widget (from which we are switching away) should be made invisible or not.
+ \param showNew Indicates if the new widget (\a widget) should be made visible or not.
+ */
+void HbStackedWidget::setCurrentWidget(QGraphicsWidget *widget, bool hideOld, bool showNew)
+{
+ Q_D(HbStackedWidget);
+ int index = d->mLayout->indexOf(widget);
+ if (index == -1) {
+ qWarning("HbStackedWidget::setCurrentWidget: Widget %p not contained in stack", widget);
+ return;
+ }
+ d->setCurrentIndex(index, currentWidget(), hideOld, showNew);
+}