mirror of
https://github.com/oguzhaninan/Stacer.git
synced 2026-06-11 17:19:37 -04:00
148 lines
3.8 KiB
C++
148 lines
3.8 KiB
C++
#include "sliding_stacked_widget.h"
|
|
|
|
SlidingStackedWidget::SlidingStackedWidget(QWidget *parent)
|
|
: QStackedWidget(parent)
|
|
{
|
|
vertical = false;
|
|
speed = 150;
|
|
animationtype = QEasingCurve::Type::Linear;
|
|
now = 0;
|
|
next = 0;
|
|
pnow = QPoint(0,0);
|
|
active = false;
|
|
}
|
|
|
|
void SlidingStackedWidget::setVerticalMode(bool vertical)
|
|
{
|
|
this->vertical = vertical;
|
|
}
|
|
|
|
void SlidingStackedWidget::setSpeed(int speed)
|
|
{
|
|
this->speed = speed;
|
|
}
|
|
|
|
void SlidingStackedWidget::setAnimation(const QEasingCurve::Type animationtype)
|
|
{
|
|
this->animationtype = animationtype;
|
|
}
|
|
|
|
void SlidingStackedWidget::slideInNext()
|
|
{
|
|
int now = currentIndex();
|
|
if (now < count() - 1)
|
|
slideInIdx(now + 1);
|
|
}
|
|
|
|
void SlidingStackedWidget::slideInPrev()
|
|
{
|
|
int now = currentIndex();
|
|
if (now > 0)
|
|
slideInIdx(now - 1);
|
|
}
|
|
|
|
void SlidingStackedWidget::slideInIdx(int idx, t_direction direction)
|
|
{
|
|
// int idx, t_direction direction=AUTOMATIC
|
|
if (idx > count() - 1) {
|
|
direction = vertical ? TOP2BOTTOM : RIGHT2LEFT;
|
|
idx = (idx) % count();
|
|
}
|
|
else if (idx < 0) {
|
|
direction = vertical ? BOTTOM2TOP : LEFT2RIGHT;
|
|
idx = (idx + count()) % count();
|
|
}
|
|
|
|
slideInWgt(widget(idx), direction);
|
|
}
|
|
|
|
void SlidingStackedWidget::slideInWgt(QWidget * newwidget, t_direction direction)
|
|
{
|
|
// do not allow re-entrance before an animation is completed.
|
|
if (active)
|
|
return ;
|
|
else
|
|
active = true;
|
|
|
|
enum t_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;
|
|
}
|
|
|
|
// calculate the shifts
|
|
|
|
int offsetx = frameRect().width();
|
|
int offsety = frameRect().height();
|
|
|
|
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();
|
|
this->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(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(this);
|
|
animgroup->addAnimation(animnow);
|
|
animgroup->addAnimation(animnext);
|
|
|
|
connect(animgroup, &QParallelAnimationGroup::finished, this, &SlidingStackedWidget::animationDoneSlot);
|
|
this->next = next;
|
|
this->now = now;
|
|
active = true;
|
|
animgroup->start();
|
|
}
|
|
|
|
void SlidingStackedWidget::animationDoneSlot()
|
|
{
|
|
setCurrentIndex(next); // this function is inherited from QStackedWidget
|
|
widget(now)->hide();
|
|
widget(now)->move(pnow);
|
|
active = false;
|
|
emit animationFinished();
|
|
}
|