Fluid Tabs

ftabarea.cpp

00001 #include <QPropertyAnimation>
00002 #include "ftabarea.h"
00003 
00012 FTabTransition::FTabTransition(QObject *parent)
00013     : QObject(parent),
00014       m_sourceView(0),
00015       m_targetView(0)
00016 {
00017     QObject::connect(this, SIGNAL(complete()), this, SLOT(deleteLater()));
00018 }
00019 
00024 void FTabTransition::setSourceView(FTabView *view)
00025 {
00026     m_sourceView = view;
00027     if (view)
00028         QObject::connect(this, SIGNAL(complete()), view, SLOT(hide()));
00029 }
00030 
00031 void FTabTransition::setTargetView(FTabView *view)
00032 {
00033     m_targetView = view;
00034 }
00035 
00042 void FTabTransition::start()
00043 {
00044     if (m_sourceView)
00045         m_sourceView->setProperty("visible", false);
00046     if (m_targetView)
00047         m_targetView->setProperty("visible", true);
00048     emit complete();
00049 }
00050 
00071 FTabAnimatedTransition::FTabAnimatedTransition(QObject *parent)
00072     : FTabTransition(parent),
00073       m_progress(0),
00074       m_duration(350)
00075 {
00076 }
00077 
00085 void FTabAnimatedTransition::setProgress(qreal progress)
00086 {
00087     if (m_progress != progress) {
00088         m_progress = progress;
00089         emit progressChanged();
00090     }
00091 }
00092 
00093 qreal FTabAnimatedTransition::progress() const
00094 {
00095     return m_progress;
00096 }
00097 
00101 void FTabAnimatedTransition::setDuration(int duration)
00102 {
00103     m_duration = duration;
00104 }
00105 
00106 int FTabAnimatedTransition::duration() const
00107 {
00108     return m_duration;
00109 }
00110 
00114 void FTabAnimatedTransition::start()
00115 {
00116     if (!m_sourceView || !m_targetView)
00117         return FTabTransition::start();
00118     m_sourceView->setProperty("visible", true);
00119     m_targetView->setProperty("visible", false);
00120 
00121     QPropertyAnimation *animation = new QPropertyAnimation(this, "progress");
00122     animation->setDuration(m_duration);
00123     animation->setStartValue(0);
00124     animation->setEndValue(1);
00125     animation->setEasingCurve(QEasingCurve::InOutQuint);
00126 
00127     QObject::connect(animation, SIGNAL(valueChanged(QVariant)),
00128                           this, SLOT(updateValue(QVariant)));
00129     QObject::connect(animation, SIGNAL(finished()),
00130                           this, SIGNAL(complete()));
00131 
00132     animation->start(QAbstractAnimation::DeleteWhenStopped);
00133 }
00134 
00149 FTabSlideTransition::FTabSlideTransition(QObject *parent)
00150     : FTabAnimatedTransition(parent),
00151       m_type(FTabSlideTransition::SlideRightToLeft)
00152 {
00153 }
00154 
00162 void FTabSlideTransition::updateCurrent(qreal value)
00163 {
00164     const QRectF r = m_sourceView->boundingRect();
00165     switch (m_type)
00166     {
00167     case SlideLeftToRight:
00168     {
00169         const qreal p = value * r.width();
00170         m_sourceView->setPos(p, 0);
00171         m_targetView->setPos(p - r.width(), 0);
00172         break;
00173     }
00174     case SlideRightToLeft:
00175     {
00176         const qreal p = value * r.width();
00177         m_sourceView->setPos(-p, 0);
00178         m_targetView->setPos(r.width() - p, 0);
00179         break;
00180     }
00181     case SlideTopToBottom:
00182     {
00183         const qreal p = value * r.height();
00184         m_sourceView->setPos(0, p);
00185         m_targetView->setPos(0, p - r.height());
00186         break;
00187     }
00188     case SlideBottomToTop:
00189     {
00190         const qreal p = value * r.height();
00191         m_sourceView->setPos(0, -p);
00192         m_targetView->setPos(0, r.height() - p);
00193         break;
00194     }
00195     default:
00196         break;
00197     } // end switch
00198     if (!m_targetView->isVisible())
00199         m_targetView->setProperty("visible", true);
00200 }
00201 
00205 void FTabSlideTransition::setTransitionType(SlideType type)
00206 {
00207     if (Random == type) {
00208         int r = (qreal) 4 * qrand() / RAND_MAX;
00209         r == 0 ? type = SlideLeftToRight :
00210         r == 1 ? type = SlideRightToLeft :
00211         r == 2 ? type = SlideTopToBottom :
00212                  type = SlideBottomToTop;
00213     }
00214     m_type = type;
00215 }
00216 
00217 FTabSlideTransition::SlideType FTabSlideTransition::transitionType() const
00218 {
00219     return m_type;
00220 }
00221 
00228 FTabView::FTabView(QDeclarativeItem *parent)
00229     : QDeclarativeItem(parent)
00230 {
00231 }
00232 
00240 FTabArea::FTabArea(QDeclarativeItem *parent)
00241     : QDeclarativeItem(parent),
00242       m_transition(0),
00243       m_current(0),
00244       m_progress(false)
00245 {
00246     setFlag(QGraphicsItem::ItemClipsToShape);
00247     setFlag(QGraphicsItem::ItemClipsChildrenToShape);
00248 }
00249 
00254 void FTabArea::setTransition(QDeclarativeComponent *transition)
00255 {
00256     m_transition = transition;
00257 }
00258 
00259 QDeclarativeComponent *FTabArea::transition() const
00260 {
00261     return m_transition;
00262 }
00263 
00267 void FTabArea::componentComplete()
00268 {
00269     FTabBar *bar = findChild<FTabBar *>();
00270     if (!bar)
00271         return;
00272     QObject::connect(bar, SIGNAL(tabActivated(int)),
00273                     this, SLOT(switchTabView(int)));
00274     m_views = findChildren<FTabView *>();
00275     for (QList<FTabView *>::const_iterator i = m_views.constBegin(); i != m_views.constEnd(); ++i)
00276         (*i)->setProperty("visible", false);
00277 
00278     QList<QDeclarativeItem *> children = findChildren<QDeclarativeItem *>();
00279     QRectF r;
00280     for (QList<QDeclarativeItem *>::const_iterator i = children.constBegin(); i != children.constEnd(); ++i) {
00281         QDeclarativeItem *item = *i;
00282         r = r.united(item->boundingRect().translated(item->x(), item->y()));
00283     }
00284     setProperty("width", r.width());
00285     setProperty("height", r.height());
00286 
00287     if (m_views.count())
00288         switchTabView(0);       // Activate the first tab, if there is one
00289 }
00290 
00296 void FTabArea::switchTabView(int i)
00297 {
00298     if (i >= m_views.count())
00299         return;
00300 
00301     QObject *object = m_transition->create();
00302     FTabTransition *transition = qobject_cast<FTabTransition *>(object);
00303     if (!transition)
00304         return;
00305     QObject::connect(transition, SIGNAL(complete()),
00306                            this, SLOT(processQueue()));
00307     transition->setSourceView(m_current);
00308     m_current = m_views.at(i);
00309     transition->setTargetView(m_current);
00310     m_transitions.enqueue(transition);
00311     if (!m_progress)
00312         processQueue();
00313 }
00314 
00318 void FTabArea::processQueue()
00319 {
00320     m_progress = false;
00321     if (m_transitions.isEmpty())
00322         return;
00323     m_progress = true;
00324     FTabTransition *transition = m_transitions.dequeue();
00325     transition->start();
00326 }
 All Classes Functions Properties