forked from mirror/nheko
parent
ff1bc797de
commit
41a85832b3
@ -1,88 +0,0 @@ |
||||
/*
|
||||
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr> |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License as published by |
||||
* the Free Software Foundation, either version 3 of the License, or |
||||
* (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
|
||||
#pragma once |
||||
|
||||
#include <QDebug> |
||||
#include <QEasingCurve> |
||||
#include <QParallelAnimationGroup> |
||||
#include <QPropertyAnimation> |
||||
#include <QStackedWidget> |
||||
#include <QWidget> |
||||
|
||||
/*
|
||||
* SlidingStackWidget allows smooth side shifting of widgets, |
||||
* in addition to the hard switching from one to another offered |
||||
* by QStackedWidget. |
||||
*/ |
||||
|
||||
class SlidingStackWidget : public QStackedWidget |
||||
{ |
||||
Q_OBJECT |
||||
|
||||
public: |
||||
// Defines the animation direction.
|
||||
enum class AnimationDirection { LEFT_TO_RIGHT, RIGHT_TO_LEFT, AUTOMATIC }; |
||||
|
||||
SlidingStackWidget(QWidget *parent); |
||||
~SlidingStackWidget(); |
||||
|
||||
public slots: |
||||
// Move to the next widget.
|
||||
void slideInNext(); |
||||
|
||||
// Move to the previous widget.
|
||||
void slideInPrevious(); |
||||
|
||||
// Move to a widget by index.
|
||||
void slideInIndex(int index, AnimationDirection direction = AnimationDirection::AUTOMATIC); |
||||
|
||||
int getWidgetIndex(QWidget *widget); |
||||
signals: |
||||
// Internal signal to alert the engine for the animation's end.
|
||||
void animationFinished(); |
||||
|
||||
protected slots: |
||||
// Internal slot to handle the end of the animation.
|
||||
void onAnimationFinished(); |
||||
|
||||
protected: |
||||
// The method that does the main work for the widget transition.
|
||||
void slideInWidget(QWidget *widget, |
||||
AnimationDirection direction = AnimationDirection::AUTOMATIC); |
||||
|
||||
// Indicates whether or not the animation is active.
|
||||
bool active_; |
||||
|
||||
// The widget currently displayed.
|
||||
QWidget *window_; |
||||
|
||||
// The speed of the animation in milliseconds.
|
||||
int speed_; |
||||
|
||||
// The animation type.
|
||||
QEasingCurve::Type animation_type_; |
||||
|
||||
// Current widget's index.
|
||||
int now_; |
||||
|
||||
// Reference point.
|
||||
QPoint current_position_; |
||||
|
||||
// Next widget's to show index.
|
||||
int next_; |
||||
}; |
@ -1,157 +0,0 @@ |
||||
/*
|
||||
* nheko Copyright (C) 2017 Konstantinos Sideris <siderisk@auth.gr> |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License as published by |
||||
* the Free Software Foundation, either version 3 of the License, or |
||||
* (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
|
||||
#include "SlidingStackWidget.h" |
||||
|
||||
SlidingStackWidget::SlidingStackWidget(QWidget *parent) |
||||
: QStackedWidget(parent) |
||||
{ |
||||
window_ = parent; |
||||
|
||||
if (parent == Q_NULLPTR) { |
||||
qDebug() << "Using nullptr for parent"; |
||||
window_ = this; |
||||
} |
||||
|
||||
current_position_ = QPoint(0, 0); |
||||
speed_ = 400; |
||||
now_ = 0; |
||||
next_ = 0; |
||||
active_ = false; |
||||
animation_type_ = QEasingCurve::InOutCirc; |
||||
} |
||||
|
||||
SlidingStackWidget::~SlidingStackWidget() |
||||
{ |
||||
} |
||||
|
||||
void |
||||
SlidingStackWidget::slideInNext() |
||||
{ |
||||
int now = currentIndex(); |
||||
|
||||
if (now < count() - 1) |
||||
slideInIndex(now + 1); |
||||
} |
||||
|
||||
void |
||||
SlidingStackWidget::slideInPrevious() |
||||
{ |
||||
int now = currentIndex(); |
||||
|
||||
if (now > 0) |
||||
slideInIndex(now - 1); |
||||
} |
||||
|
||||
void |
||||
SlidingStackWidget::slideInIndex(int index, AnimationDirection direction) |
||||
{ |
||||
// Take into consideration possible index overflow/undeflow.
|
||||
if (index > count() - 1) { |
||||
direction = AnimationDirection::RIGHT_TO_LEFT; |
||||
index = index % count(); |
||||
} else if (index < 0) { |
||||
direction = AnimationDirection::LEFT_TO_RIGHT; |
||||
index = (index + count()) % count(); |
||||
} |
||||
|
||||
slideInWidget(widget(index), direction); |
||||
} |
||||
|
||||
void |
||||
SlidingStackWidget::slideInWidget(QWidget *next_widget, AnimationDirection direction) |
||||
{ |
||||
// If an animation is currenlty executing we should wait for it to finish before
|
||||
// another transition can start.
|
||||
if (active_) |
||||
return; |
||||
|
||||
active_ = true; |
||||
|
||||
int now = currentIndex(); |
||||
int next = indexOf(next_widget); |
||||
|
||||
if (now == next) { |
||||
active_ = false; |
||||
return; |
||||
} |
||||
|
||||
int offset_x = frameRect().width(); |
||||
|
||||
next_widget->setGeometry(0, 0, offset_x, 0); |
||||
|
||||
if (direction == AnimationDirection::LEFT_TO_RIGHT) { |
||||
offset_x = -offset_x; |
||||
} |
||||
|
||||
QPoint pnext = next_widget->pos(); |
||||
QPoint pnow = widget(now)->pos(); |
||||
current_position_ = pnow; |
||||
|
||||
// Reposition the next widget outside of the display area.
|
||||
next_widget->move(pnext.x() - offset_x, pnext.y()); |
||||
|
||||
// Make the widget visible.
|
||||
next_widget->show(); |
||||
next_widget->raise(); |
||||
|
||||
// Animate both the next and now widget.
|
||||
QPropertyAnimation *animation_now = new QPropertyAnimation(widget(now), "pos", this); |
||||
|
||||
animation_now->setDuration(speed_); |
||||
animation_now->setEasingCurve(animation_type_); |
||||
animation_now->setStartValue(QPoint(pnow.x(), pnow.y())); |
||||
animation_now->setEndValue(QPoint(pnow.x() + offset_x, pnow.y())); |
||||
|
||||
QPropertyAnimation *animation_next = new QPropertyAnimation(next_widget, "pos", this); |
||||
|
||||
animation_next->setDuration(speed_); |
||||
animation_next->setEasingCurve(animation_type_); |
||||
animation_next->setStartValue(QPoint(pnext.x() - offset_x, pnext.y())); |
||||
animation_next->setEndValue(QPoint(pnext.x(), pnext.y())); |
||||
|
||||
QParallelAnimationGroup *animation_group = new QParallelAnimationGroup(this); |
||||
|
||||
animation_group->addAnimation(animation_now); |
||||
animation_group->addAnimation(animation_next); |
||||
|
||||
connect(animation_group, SIGNAL(finished()), this, SLOT(onAnimationFinished())); |
||||
|
||||
next_ = next; |
||||
now_ = now; |
||||
animation_group->start(); |
||||
} |
||||
|
||||
void |
||||
SlidingStackWidget::onAnimationFinished() |
||||
{ |
||||
setCurrentIndex(next_); |
||||
|
||||
// The old widget is no longer necessary so we can hide it and
|
||||
// move it back to its original position.
|
||||
widget(now_)->hide(); |
||||
widget(now_)->move(current_position_); |
||||
|
||||
active_ = false; |
||||
emit animationFinished(); |
||||
} |
||||
|
||||
int |
||||
SlidingStackWidget::getWidgetIndex(QWidget *widget) |
||||
{ |
||||
return indexOf(widget); |
||||
} |
Loading…
Reference in new issue