void unicorn::SlidingStackedWidget::slideWidget( QWidget* newwidget ) { m_active=true; enum t_direction directionhint; int now=currentIndex(); //currentIndex() is a function inherited from QStackedWidget int next=indexOf(newwidget); if ( now == next ) { m_active=false; emit currentChanged( currentIndex() ); return; } else if ( now < next ) { directionhint = m_vertical ? TOP2BOTTOM : RIGHT2LEFT; } else { directionhint = m_vertical ? BOTTOM2TOP : LEFT2RIGHT; } //NOW.... //calculate the shifts int offsetx=frameRect().width(); //inherited from mother int offsety=frameRect().height();//inherited from mother //the following is important, to ensure that the new widget //has correct geometry information when sliding in first time widget(next)->setGeometry ( 0, 0, offsetx, offsety ); if (directionhint==BOTTOM2TOP) { offsetx=0; offsety=-offsety; } else if (directionhint==TOP2BOTTOM) { offsetx=0; //offsety=offsety; } else if (directionhint==RIGHT2LEFT) { offsetx=-offsetx; offsety=0; } else if (directionhint==LEFT2RIGHT) { //offsetx=offsetx; offsety=0; } //re-position the next widget outside/aside of the display area QPoint pnext=widget(next)->pos(); QPoint pnow=widget(now)->pos(); m_pnow=pnow; widget(next)->move(pnext.x()-offsetx,pnext.y()-offsety); //make it visible/show widget(next)->show(); widget(next)->raise(); //animate both, the now and next widget to the side, using animation framework QPropertyAnimation *animnow = new QPropertyAnimation(widget(now), "pos"); animnow->setDuration(m_speed); animnow->setEasingCurve(m_animationtype); animnow->setStartValue(QPoint(pnow.x(), pnow.y())); animnow->setEndValue(QPoint(offsetx+pnow.x(), offsety+pnow.y())); QPropertyAnimation *animnext = new QPropertyAnimation(widget(next), "pos"); animnext->setDuration(m_speed); animnext->setEasingCurve(m_animationtype); animnext->setStartValue(QPoint(-offsetx+pnext.x(), offsety+pnext.y())); animnext->setEndValue(QPoint(pnext.x(), pnext.y())); QParallelAnimationGroup *animgroup = new QParallelAnimationGroup; animgroup->addAnimation(animnow); animgroup->addAnimation(animnext); QObject::connect(animgroup, SIGNAL(finished()),this,SLOT(animationDoneSlot())); m_next=next; m_now=now; m_active=true; animgroup->start(); }
void SlidingStackedWidget::slideInWgt(QWidget * newwidget, enum t_direction direction) { if (m_active) { return; // at the moment, do not allow re-entrance before an animation is completed. //other possibility may be to finish the previous animation abrupt, or //to revert the previous animation with a counter animation, before going ahead //or to revert the previous animation abrupt //and all those only, if the newwidget is not the same as that of the previous running animation. } else m_active=true; enum t_direction directionhint; int now=currentIndex(); //currentIndex() is a function inherited from QStackedWidget int next=indexOf(newwidget); if (now==next) { m_active=false; return; } else if (now<next){ directionhint=m_vertical ? TOP2BOTTOM : RIGHT2LEFT; } else { directionhint=m_vertical ? BOTTOM2TOP : LEFT2RIGHT; } if (direction == AUTOMATIC) { direction=directionhint; } //NOW.... //calculate the shifts int offsetx=frameRect().width(); //inherited from mother int offsety=frameRect().height();//inherited from mother //the following is important, to ensure that the new widget //has correct geometry information when sliding in first time widget(next)->setGeometry ( 0, 0, offsetx, offsety ); if (direction==BOTTOM2TOP) { offsetx=0; offsety=-offsety; } else if (direction==TOP2BOTTOM) { offsetx=0; //offsety=offsety; } else if (direction==RIGHT2LEFT) { offsetx=-offsetx; offsety=0; } else if (direction==LEFT2RIGHT) { //offsetx=offsetx; offsety=0; } //re-position the next widget outside/aside of the display area QPoint pnext=widget(next)->pos(); QPoint pnow=widget(now)->pos(); m_pnow=pnow; widget(next)->move(pnext.x()-offsetx,pnext.y()-offsety); //make it visible/show widget(next)->show(); widget(next)->raise(); //animate both, the now and next widget to the side, using animation framework QPropertyAnimation *animnow = new QPropertyAnimation(widget(now), "pos"); animnow->setDuration(m_speed); animnow->setEasingCurve(m_animationtype); animnow->setStartValue(QPoint(pnow.x(), pnow.y())); animnow->setEndValue(QPoint(offsetx+pnow.x(), offsety+pnow.y())); QPropertyAnimation *animnext = new QPropertyAnimation(widget(next), "pos"); animnext->setDuration(m_speed); animnext->setEasingCurve(m_animationtype); animnext->setStartValue(QPoint(-offsetx+pnext.x(), offsety+pnext.y())); animnext->setEndValue(QPoint(pnext.x(), pnext.y())); QParallelAnimationGroup *animgroup = new QParallelAnimationGroup; animgroup->addAnimation(animnow); animgroup->addAnimation(animnext); QObject::connect(animgroup, SIGNAL(finished()),this,SLOT(animationDoneSlot())); m_next=next; m_now=now; m_active=true; animgroup->start(); emit this->animationStarted(next); //note; the rest is done via a connect from the animation ready; //animation->finished() provides a signal when animation is done; //so we connect this to some post processing slot, //that we implement here below in animationDoneSlot. }
void SlidingStackedWidget::slideInWgt(QWidget * newWidget, Direction direction) { if (active) { // At the moment, do not allow re-entrance before an animation is // completed. Other possibility may be to finish the previous animation // abrupt, or to revert the previous animation with a counter // animation, before going ahead or to revert the previous animation // abrupt and all those only, if the newwidget is not the same as that // of the previous running animation. return; } else active=true; Direction directionHint; int now = currentIndex(); int next = indexOf(newWidget); if (now == next) { active = false; return; } else if (now < next) directionHint = vertical ? TOP2BOTTOM : RIGHT2LEFT; else directionHint=vertical ? BOTTOM2TOP : LEFT2RIGHT; if (direction == AUTOMATIC) direction = directionHint; int offsetX = frameRect().width(); int offsetY = frameRect().height(); // The following is important, to ensure that the new widget // has correct geometry information when sliding in first time widget(next)->setGeometry(0, 0, offsetX, offsetY); if (direction == BOTTOM2TOP) { offsetX = 0; offsetY = -offsetY; } else if (direction == TOP2BOTTOM) offsetX = 0; else if (direction == RIGHT2LEFT) { offsetX = -offsetX; offsetY = 0; } else if (direction == LEFT2RIGHT) offsetY = 0; // Re-position the next widget outside/aside of the display area QPoint pNext = widget(next)->pos(); QPoint pNow = widget(now)->pos(); pNow = pNow; widget(next)->move(pNext.x() - offsetX, pNext.y() - offsetY); widget(next)->show(); widget(next)->raise(); // Animate both, the now and next widget to the side, using animation framework QPropertyAnimation *animNow = new QPropertyAnimation(widget(now), "pos"); animNow->setDuration(speed); animNow->setEasingCurve(animationType); animNow->setStartValue(QPoint(pNow.x(), pNow.y())); animNow->setEndValue(QPoint(offsetX + pNow.x(), offsetY + pNow.y())); QPropertyAnimation *animNext = new QPropertyAnimation(widget(next), "pos"); animNext->setDuration(speed); animNext->setEasingCurve(animationType); animNext->setStartValue(QPoint(-offsetX + pNext.x(), offsetY + pNext.y())); animNext->setEndValue(QPoint(pNext.x(), pNext.y())); QParallelAnimationGroup *animGroup = new QParallelAnimationGroup; animGroup->addAnimation(animNow); animGroup->addAnimation(animNext); QObject::connect(animGroup, SIGNAL(finished()), this, SLOT(animationDoneSlot())); this->next = next; this->now = now; active = true; animGroup->start(); // Note: the rest is done via a connect from the animation ready; // animation->finished() provides a signal when animation is done; // so we connect this to some post processing slot, // that we implement here below in animationDoneSlot. }
void SlidingStackedWidget::slideInWgt(QWidget * newwidget, enum t_direction direction) { if (m_active) { animationDoneSlot(); m_animationGroup->stop(); m_animationGroup->disconnect(); } m_active=true; enum t_direction directionhint; int now=currentIndex(); //currentIndex() is a function inherited from QStackedWidget int next=indexOf(newwidget); if (now==next) { m_active=false; return; } else if (now<next){ directionhint=m_vertical ? TOP2BOTTOM : RIGHT2LEFT; } else { directionhint=m_vertical ? BOTTOM2TOP : LEFT2RIGHT; } if (direction == AUTOMATIC) { direction=directionhint; } //NOW.... //calculate the shifts int offsetx=frameRect().width(); //inherited from mother int offsety=frameRect().height();//inherited from mother //the following is important, to ensure that the new widget //has correct geometry information when sliding in first time widget(next)->setGeometry ( 0, 0, offsetx, offsety ); if (direction==BOTTOM2TOP) { offsetx=0; offsety=-offsety; } else if (direction==TOP2BOTTOM) { offsetx=0; //offsety=offsety; } else if (direction==RIGHT2LEFT) { offsetx=-offsetx; offsety=0; } else if (direction==LEFT2RIGHT) { //offsetx=offsetx; offsety=0; } //re-position the next widget outside/aside of the display area QPoint pnext=widget(next)->pos(); QPoint pnow=widget(now)->pos(); m_pnow=pnow; widget(next)->move(pnext.x()-offsetx,pnext.y()-offsety); //make it visible/show widget(next)->show(); widget(next)->raise(); //animate both, the now and next widget to the side, using animation framework m_animnow->setTargetObject(widget(now)); m_animnow->setPropertyName("pos"); m_animnow->setDuration(m_speed); m_animnow->setEasingCurve(m_animationtype); m_animnow->setStartValue(QPoint(pnow.x(), pnow.y())); m_animnow->setEndValue(QPoint(offsetx+pnow.x(), offsety+pnow.y())); m_animnext->setTargetObject(widget(next)); m_animnext->setPropertyName("pos"); m_animnext->setDuration(m_speed); m_animnext->setEasingCurve(m_animationtype); m_animnext->setStartValue(QPoint(-offsetx+pnext.x(), offsety+pnext.y())); m_animnext->setEndValue(QPoint(pnext.x(), pnext.y())); QObject::connect(m_animationGroup, SIGNAL(finished()),this,SLOT(animationDoneSlot())); m_next=next; m_now=now; m_active=true; m_animationGroup->start(); //note; the rest is done via a connect from the animation ready; //animation->finished() provides a signal when animation is done; //so we connect this to some post processing slot, //that we implement here below in animationDoneSlot. }