Extract TimeLine into its own header
This commit is contained in:
parent
889180b685
commit
56e384e527
16 changed files with 492 additions and 455 deletions
|
@ -7,7 +7,7 @@
|
||||||
SPDX-License-Identifier: GPL-2.0-or-later
|
SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "libkwineffects/kwineffects.h"
|
#include "libkwineffects/timeline.h"
|
||||||
|
|
||||||
#include <QTest>
|
#include <QTest>
|
||||||
|
|
||||||
|
|
|
@ -117,6 +117,7 @@ target_sources(kwin PRIVATE
|
||||||
libkwineffects/kwinoffscreenquickview.cpp
|
libkwineffects/kwinoffscreenquickview.cpp
|
||||||
libkwineffects/kwinquickeffect.cpp
|
libkwineffects/kwinquickeffect.cpp
|
||||||
libkwineffects/logging.cpp
|
libkwineffects/logging.cpp
|
||||||
|
libkwineffects/timeline.cpp
|
||||||
lidswitchtracker.cpp
|
lidswitchtracker.cpp
|
||||||
main.cpp
|
main.cpp
|
||||||
modifier_only_shortcuts.cpp
|
modifier_only_shortcuts.cpp
|
||||||
|
@ -440,6 +441,7 @@ install(FILES
|
||||||
libkwineffects/kwinoffscreeneffect.h
|
libkwineffects/kwinoffscreeneffect.h
|
||||||
libkwineffects/kwinoffscreenquickview.h
|
libkwineffects/kwinoffscreenquickview.h
|
||||||
libkwineffects/kwinquickeffect.h
|
libkwineffects/kwinquickeffect.h
|
||||||
|
libkwineffects/timeline.h
|
||||||
DESTINATION ${KDE_INSTALL_INCLUDEDIR}/kwin/libkwineffects COMPONENT Devel)
|
DESTINATION ${KDE_INSTALL_INCLUDEDIR}/kwin/libkwineffects COMPONENT Devel)
|
||||||
|
|
||||||
install(FILES
|
install(FILES
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "libkwineffects/kwinanimationeffect.h"
|
#include "libkwineffects/kwinanimationeffect.h"
|
||||||
|
#include "libkwineffects/timeline.h"
|
||||||
|
|
||||||
#include <QEasingCurve>
|
#include <QEasingCurve>
|
||||||
|
|
||||||
|
|
|
@ -1713,207 +1713,6 @@ EffectWindow *WindowMotionManager::windowAtPoint(QPoint point, bool useStackingO
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************
|
|
||||||
TimeLine
|
|
||||||
***************************************************************/
|
|
||||||
|
|
||||||
class Q_DECL_HIDDEN TimeLine::Data : public QSharedData
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
std::chrono::milliseconds duration;
|
|
||||||
Direction direction;
|
|
||||||
QEasingCurve easingCurve;
|
|
||||||
|
|
||||||
std::chrono::milliseconds elapsed = std::chrono::milliseconds::zero();
|
|
||||||
std::optional<std::chrono::milliseconds> lastTimestamp = std::nullopt;
|
|
||||||
bool done = false;
|
|
||||||
RedirectMode sourceRedirectMode = RedirectMode::Relaxed;
|
|
||||||
RedirectMode targetRedirectMode = RedirectMode::Strict;
|
|
||||||
};
|
|
||||||
|
|
||||||
TimeLine::TimeLine(std::chrono::milliseconds duration, Direction direction)
|
|
||||||
: d(new Data)
|
|
||||||
{
|
|
||||||
Q_ASSERT(duration > std::chrono::milliseconds::zero());
|
|
||||||
d->duration = duration;
|
|
||||||
d->direction = direction;
|
|
||||||
}
|
|
||||||
|
|
||||||
TimeLine::TimeLine(const TimeLine &other)
|
|
||||||
: d(other.d)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
TimeLine::~TimeLine() = default;
|
|
||||||
|
|
||||||
qreal TimeLine::progress() const
|
|
||||||
{
|
|
||||||
return static_cast<qreal>(d->elapsed.count()) / d->duration.count();
|
|
||||||
}
|
|
||||||
|
|
||||||
qreal TimeLine::value() const
|
|
||||||
{
|
|
||||||
const qreal t = progress();
|
|
||||||
return d->easingCurve.valueForProgress(
|
|
||||||
d->direction == Backward ? 1.0 - t : t);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TimeLine::advance(std::chrono::milliseconds timestamp)
|
|
||||||
{
|
|
||||||
if (d->done) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::chrono::milliseconds delta = std::chrono::milliseconds::zero();
|
|
||||||
if (d->lastTimestamp.has_value()) {
|
|
||||||
delta = timestamp - d->lastTimestamp.value();
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_ASSERT(delta >= std::chrono::milliseconds::zero());
|
|
||||||
d->lastTimestamp = timestamp;
|
|
||||||
|
|
||||||
d->elapsed += delta;
|
|
||||||
if (d->elapsed >= d->duration) {
|
|
||||||
d->elapsed = d->duration;
|
|
||||||
d->done = true;
|
|
||||||
d->lastTimestamp = std::nullopt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::chrono::milliseconds TimeLine::elapsed() const
|
|
||||||
{
|
|
||||||
return d->elapsed;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TimeLine::setElapsed(std::chrono::milliseconds elapsed)
|
|
||||||
{
|
|
||||||
Q_ASSERT(elapsed >= std::chrono::milliseconds::zero());
|
|
||||||
if (elapsed == d->elapsed) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
reset();
|
|
||||||
|
|
||||||
d->elapsed = elapsed;
|
|
||||||
|
|
||||||
if (d->elapsed >= d->duration) {
|
|
||||||
d->elapsed = d->duration;
|
|
||||||
d->done = true;
|
|
||||||
d->lastTimestamp = std::nullopt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::chrono::milliseconds TimeLine::duration() const
|
|
||||||
{
|
|
||||||
return d->duration;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TimeLine::setDuration(std::chrono::milliseconds duration)
|
|
||||||
{
|
|
||||||
Q_ASSERT(duration > std::chrono::milliseconds::zero());
|
|
||||||
if (duration == d->duration) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
d->elapsed = std::chrono::milliseconds(qRound(progress() * duration.count()));
|
|
||||||
d->duration = duration;
|
|
||||||
if (d->elapsed == d->duration) {
|
|
||||||
d->done = true;
|
|
||||||
d->lastTimestamp = std::nullopt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TimeLine::Direction TimeLine::direction() const
|
|
||||||
{
|
|
||||||
return d->direction;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TimeLine::setDirection(TimeLine::Direction direction)
|
|
||||||
{
|
|
||||||
if (d->direction == direction) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
d->direction = direction;
|
|
||||||
|
|
||||||
if (d->elapsed > std::chrono::milliseconds::zero()
|
|
||||||
|| d->sourceRedirectMode == RedirectMode::Strict) {
|
|
||||||
d->elapsed = d->duration - d->elapsed;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (d->done && d->targetRedirectMode == RedirectMode::Relaxed) {
|
|
||||||
d->done = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (d->elapsed >= d->duration) {
|
|
||||||
d->done = true;
|
|
||||||
d->lastTimestamp = std::nullopt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TimeLine::toggleDirection()
|
|
||||||
{
|
|
||||||
setDirection(d->direction == Forward ? Backward : Forward);
|
|
||||||
}
|
|
||||||
|
|
||||||
QEasingCurve TimeLine::easingCurve() const
|
|
||||||
{
|
|
||||||
return d->easingCurve;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TimeLine::setEasingCurve(const QEasingCurve &easingCurve)
|
|
||||||
{
|
|
||||||
d->easingCurve = easingCurve;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TimeLine::setEasingCurve(QEasingCurve::Type type)
|
|
||||||
{
|
|
||||||
d->easingCurve.setType(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TimeLine::running() const
|
|
||||||
{
|
|
||||||
return d->elapsed != std::chrono::milliseconds::zero()
|
|
||||||
&& d->elapsed != d->duration;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TimeLine::done() const
|
|
||||||
{
|
|
||||||
return d->done;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TimeLine::reset()
|
|
||||||
{
|
|
||||||
d->lastTimestamp = std::nullopt;
|
|
||||||
d->elapsed = std::chrono::milliseconds::zero();
|
|
||||||
d->done = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
TimeLine::RedirectMode TimeLine::sourceRedirectMode() const
|
|
||||||
{
|
|
||||||
return d->sourceRedirectMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TimeLine::setSourceRedirectMode(RedirectMode mode)
|
|
||||||
{
|
|
||||||
d->sourceRedirectMode = mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
TimeLine::RedirectMode TimeLine::targetRedirectMode() const
|
|
||||||
{
|
|
||||||
return d->targetRedirectMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TimeLine::setTargetRedirectMode(RedirectMode mode)
|
|
||||||
{
|
|
||||||
d->targetRedirectMode = mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
TimeLine &TimeLine::operator=(const TimeLine &other)
|
|
||||||
{
|
|
||||||
d = other.d;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
#include "moc_kwineffects.cpp"
|
#include "moc_kwineffects.cpp"
|
||||||
|
|
|
@ -3473,257 +3473,6 @@ private:
|
||||||
QSet<EffectWindow *> m_movingWindowsSet;
|
QSet<EffectWindow *> m_movingWindowsSet;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* The TimeLine class is a helper for controlling animations.
|
|
||||||
*/
|
|
||||||
class KWIN_EXPORT TimeLine
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Direction of the timeline.
|
|
||||||
*
|
|
||||||
* When the direction of the timeline is Forward, the progress
|
|
||||||
* value will go from 0.0 to 1.0.
|
|
||||||
*
|
|
||||||
* When the direction of the timeline is Backward, the progress
|
|
||||||
* value will go from 1.0 to 0.0.
|
|
||||||
*/
|
|
||||||
enum Direction {
|
|
||||||
Forward,
|
|
||||||
Backward
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a new instance of TimeLine.
|
|
||||||
*
|
|
||||||
* @param duration Duration of the timeline, in milliseconds
|
|
||||||
* @param direction Direction of the timeline
|
|
||||||
* @since 5.14
|
|
||||||
*/
|
|
||||||
explicit TimeLine(std::chrono::milliseconds duration = std::chrono::milliseconds(1000),
|
|
||||||
Direction direction = Forward);
|
|
||||||
TimeLine(const TimeLine &other);
|
|
||||||
~TimeLine();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the current value of the timeline.
|
|
||||||
*
|
|
||||||
* @since 5.14
|
|
||||||
*/
|
|
||||||
qreal value() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Advances the timeline to the specified @a timestamp.
|
|
||||||
*/
|
|
||||||
void advance(std::chrono::milliseconds timestamp);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the number of elapsed milliseconds.
|
|
||||||
*
|
|
||||||
* @see setElapsed
|
|
||||||
* @since 5.14
|
|
||||||
*/
|
|
||||||
std::chrono::milliseconds elapsed() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the number of elapsed milliseconds.
|
|
||||||
*
|
|
||||||
* This method overwrites previous value of elapsed milliseconds.
|
|
||||||
* If the new value of elapsed milliseconds is greater or equal
|
|
||||||
* to duration of the timeline, the timeline will be finished, i.e.
|
|
||||||
* proceeding TimeLine::done method calls will return @c true.
|
|
||||||
* Please don't use it. Instead, use TimeLine::update.
|
|
||||||
*
|
|
||||||
* @note The new number of elapsed milliseconds should be a non-negative
|
|
||||||
* number, i.e. it should be greater or equal to 0.
|
|
||||||
*
|
|
||||||
* @param elapsed The new number of elapsed milliseconds
|
|
||||||
* @see elapsed
|
|
||||||
* @since 5.14
|
|
||||||
*/
|
|
||||||
void setElapsed(std::chrono::milliseconds elapsed);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the duration of the timeline.
|
|
||||||
*
|
|
||||||
* @returns Duration of the timeline, in milliseconds
|
|
||||||
* @see setDuration
|
|
||||||
* @since 5.14
|
|
||||||
*/
|
|
||||||
std::chrono::milliseconds duration() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the duration of the timeline.
|
|
||||||
*
|
|
||||||
* In addition to setting new value of duration, the timeline will
|
|
||||||
* try to retarget the number of elapsed milliseconds to match
|
|
||||||
* as close as possible old progress value. If the new duration
|
|
||||||
* is much smaller than old duration, there is a big chance that
|
|
||||||
* the timeline will be finished after setting new duration.
|
|
||||||
*
|
|
||||||
* @note The new duration should be a positive number, i.e. it
|
|
||||||
* should be greater or equal to 1.
|
|
||||||
*
|
|
||||||
* @param duration The new duration of the timeline, in milliseconds
|
|
||||||
* @see duration
|
|
||||||
* @since 5.14
|
|
||||||
*/
|
|
||||||
void setDuration(std::chrono::milliseconds duration);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the direction of the timeline.
|
|
||||||
*
|
|
||||||
* @returns Direction of the timeline(TimeLine::Forward or TimeLine::Backward)
|
|
||||||
* @see setDirection
|
|
||||||
* @see toggleDirection
|
|
||||||
* @since 5.14
|
|
||||||
*/
|
|
||||||
Direction direction() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the direction of the timeline.
|
|
||||||
*
|
|
||||||
* @param direction The new direction of the timeline
|
|
||||||
* @see direction
|
|
||||||
* @see toggleDirection
|
|
||||||
* @since 5.14
|
|
||||||
*/
|
|
||||||
void setDirection(Direction direction);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Toggles the direction of the timeline.
|
|
||||||
*
|
|
||||||
* If the direction of the timeline was TimeLine::Forward, it becomes
|
|
||||||
* TimeLine::Backward, and vice verca.
|
|
||||||
*
|
|
||||||
* @see direction
|
|
||||||
* @see setDirection
|
|
||||||
* @since 5.14
|
|
||||||
*/
|
|
||||||
void toggleDirection();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the easing curve of the timeline.
|
|
||||||
*
|
|
||||||
* @see setEasingCurve
|
|
||||||
* @since 5.14
|
|
||||||
*/
|
|
||||||
QEasingCurve easingCurve() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets new easing curve.
|
|
||||||
*
|
|
||||||
* @param easingCurve An easing curve to be set
|
|
||||||
* @see easingCurve
|
|
||||||
* @since 5.14
|
|
||||||
*/
|
|
||||||
void setEasingCurve(const QEasingCurve &easingCurve);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets new easing curve by providing its type.
|
|
||||||
*
|
|
||||||
* @param type Type of the easing curve(e.g. QEasingCurve::InCubic, etc)
|
|
||||||
* @see easingCurve
|
|
||||||
* @since 5.14
|
|
||||||
*/
|
|
||||||
void setEasingCurve(QEasingCurve::Type type);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether the timeline is currently in progress.
|
|
||||||
*
|
|
||||||
* @see done
|
|
||||||
* @since 5.14
|
|
||||||
*/
|
|
||||||
bool running() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether the timeline is finished.
|
|
||||||
*
|
|
||||||
* @see reset
|
|
||||||
* @since 5.14
|
|
||||||
*/
|
|
||||||
bool done() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resets the timeline to initial state.
|
|
||||||
*
|
|
||||||
* @since 5.14
|
|
||||||
*/
|
|
||||||
void reset();
|
|
||||||
|
|
||||||
enum class RedirectMode {
|
|
||||||
Strict,
|
|
||||||
Relaxed
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the redirect mode for the source position.
|
|
||||||
*
|
|
||||||
* The redirect mode controls behavior of the timeline when its direction is
|
|
||||||
* changed at the source position, e.g. what should we do when the timeline
|
|
||||||
* initially goes forward and we change its direction to go backward.
|
|
||||||
*
|
|
||||||
* In the strict mode, the timeline will stop.
|
|
||||||
*
|
|
||||||
* In the relaxed mode, the timeline will go in the new direction. For example,
|
|
||||||
* if the timeline goes forward(from 0 to 1), then with the new direction it
|
|
||||||
* will go backward(from 1 to 0).
|
|
||||||
*
|
|
||||||
* The default is RedirectMode::Relaxed.
|
|
||||||
*
|
|
||||||
* @see targetRedirectMode
|
|
||||||
* @since 5.15
|
|
||||||
*/
|
|
||||||
RedirectMode sourceRedirectMode() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the redirect mode for the source position.
|
|
||||||
*
|
|
||||||
* @param mode The new mode.
|
|
||||||
* @since 5.15
|
|
||||||
*/
|
|
||||||
void setSourceRedirectMode(RedirectMode mode);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the redirect mode for the target position.
|
|
||||||
*
|
|
||||||
* The redirect mode controls behavior of the timeline when its direction is
|
|
||||||
* changed at the target position.
|
|
||||||
*
|
|
||||||
* In the strict mode, subsequent update calls won't have any effect on the
|
|
||||||
* current value of the timeline.
|
|
||||||
*
|
|
||||||
* In the relaxed mode, the timeline will go in the new direction.
|
|
||||||
*
|
|
||||||
* The default is RedirectMode::Strict.
|
|
||||||
*
|
|
||||||
* @see sourceRedirectMode
|
|
||||||
* @since 5.15
|
|
||||||
*/
|
|
||||||
RedirectMode targetRedirectMode() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the redirect mode for the target position.
|
|
||||||
*
|
|
||||||
* @param mode The new mode.
|
|
||||||
* @since 5.15
|
|
||||||
*/
|
|
||||||
void setTargetRedirectMode(RedirectMode mode);
|
|
||||||
|
|
||||||
TimeLine &operator=(const TimeLine &other);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @returns a value between 0 and 1 defining the progress of the timeline
|
|
||||||
*
|
|
||||||
* @since 5.23
|
|
||||||
*/
|
|
||||||
qreal progress() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
class Data;
|
|
||||||
QSharedDataPointer<Data> d;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pointer to the global EffectsHandler object.
|
* Pointer to the global EffectsHandler object.
|
||||||
*/
|
*/
|
||||||
|
@ -3905,7 +3654,5 @@ inline void EffectWindow::addLayerRepaint(int x, int y, int w, int h)
|
||||||
} // namespace
|
} // namespace
|
||||||
Q_DECLARE_METATYPE(KWin::EffectWindow *)
|
Q_DECLARE_METATYPE(KWin::EffectWindow *)
|
||||||
Q_DECLARE_METATYPE(KWin::EffectWindowList)
|
Q_DECLARE_METATYPE(KWin::EffectWindowList)
|
||||||
Q_DECLARE_METATYPE(KWin::TimeLine)
|
|
||||||
Q_DECLARE_METATYPE(KWin::TimeLine::Direction)
|
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
209
src/libkwineffects/timeline.cpp
Normal file
209
src/libkwineffects/timeline.cpp
Normal file
|
@ -0,0 +1,209 @@
|
||||||
|
/*
|
||||||
|
SPDX-FileCopyrightText: 2018 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "libkwineffects/timeline.h"
|
||||||
|
|
||||||
|
namespace KWin
|
||||||
|
{
|
||||||
|
|
||||||
|
class Q_DECL_HIDDEN TimeLine::Data : public QSharedData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::chrono::milliseconds duration;
|
||||||
|
Direction direction;
|
||||||
|
QEasingCurve easingCurve;
|
||||||
|
|
||||||
|
std::chrono::milliseconds elapsed = std::chrono::milliseconds::zero();
|
||||||
|
std::optional<std::chrono::milliseconds> lastTimestamp = std::nullopt;
|
||||||
|
bool done = false;
|
||||||
|
RedirectMode sourceRedirectMode = RedirectMode::Relaxed;
|
||||||
|
RedirectMode targetRedirectMode = RedirectMode::Strict;
|
||||||
|
};
|
||||||
|
|
||||||
|
TimeLine::TimeLine(std::chrono::milliseconds duration, Direction direction)
|
||||||
|
: d(new Data)
|
||||||
|
{
|
||||||
|
Q_ASSERT(duration > std::chrono::milliseconds::zero());
|
||||||
|
d->duration = duration;
|
||||||
|
d->direction = direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
TimeLine::TimeLine(const TimeLine &other)
|
||||||
|
: d(other.d)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
TimeLine::~TimeLine() = default;
|
||||||
|
|
||||||
|
qreal TimeLine::progress() const
|
||||||
|
{
|
||||||
|
return static_cast<qreal>(d->elapsed.count()) / d->duration.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal TimeLine::value() const
|
||||||
|
{
|
||||||
|
const qreal t = progress();
|
||||||
|
return d->easingCurve.valueForProgress(
|
||||||
|
d->direction == Backward ? 1.0 - t : t);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimeLine::advance(std::chrono::milliseconds timestamp)
|
||||||
|
{
|
||||||
|
if (d->done) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::chrono::milliseconds delta = std::chrono::milliseconds::zero();
|
||||||
|
if (d->lastTimestamp.has_value()) {
|
||||||
|
delta = timestamp - d->lastTimestamp.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_ASSERT(delta >= std::chrono::milliseconds::zero());
|
||||||
|
d->lastTimestamp = timestamp;
|
||||||
|
|
||||||
|
d->elapsed += delta;
|
||||||
|
if (d->elapsed >= d->duration) {
|
||||||
|
d->elapsed = d->duration;
|
||||||
|
d->done = true;
|
||||||
|
d->lastTimestamp = std::nullopt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::chrono::milliseconds TimeLine::elapsed() const
|
||||||
|
{
|
||||||
|
return d->elapsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimeLine::setElapsed(std::chrono::milliseconds elapsed)
|
||||||
|
{
|
||||||
|
Q_ASSERT(elapsed >= std::chrono::milliseconds::zero());
|
||||||
|
if (elapsed == d->elapsed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
reset();
|
||||||
|
|
||||||
|
d->elapsed = elapsed;
|
||||||
|
|
||||||
|
if (d->elapsed >= d->duration) {
|
||||||
|
d->elapsed = d->duration;
|
||||||
|
d->done = true;
|
||||||
|
d->lastTimestamp = std::nullopt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::chrono::milliseconds TimeLine::duration() const
|
||||||
|
{
|
||||||
|
return d->duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimeLine::setDuration(std::chrono::milliseconds duration)
|
||||||
|
{
|
||||||
|
Q_ASSERT(duration > std::chrono::milliseconds::zero());
|
||||||
|
if (duration == d->duration) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
d->elapsed = std::chrono::milliseconds(qRound(progress() * duration.count()));
|
||||||
|
d->duration = duration;
|
||||||
|
if (d->elapsed == d->duration) {
|
||||||
|
d->done = true;
|
||||||
|
d->lastTimestamp = std::nullopt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TimeLine::Direction TimeLine::direction() const
|
||||||
|
{
|
||||||
|
return d->direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimeLine::setDirection(TimeLine::Direction direction)
|
||||||
|
{
|
||||||
|
if (d->direction == direction) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
d->direction = direction;
|
||||||
|
|
||||||
|
if (d->elapsed > std::chrono::milliseconds::zero()
|
||||||
|
|| d->sourceRedirectMode == RedirectMode::Strict) {
|
||||||
|
d->elapsed = d->duration - d->elapsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d->done && d->targetRedirectMode == RedirectMode::Relaxed) {
|
||||||
|
d->done = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d->elapsed >= d->duration) {
|
||||||
|
d->done = true;
|
||||||
|
d->lastTimestamp = std::nullopt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimeLine::toggleDirection()
|
||||||
|
{
|
||||||
|
setDirection(d->direction == Forward ? Backward : Forward);
|
||||||
|
}
|
||||||
|
|
||||||
|
QEasingCurve TimeLine::easingCurve() const
|
||||||
|
{
|
||||||
|
return d->easingCurve;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimeLine::setEasingCurve(const QEasingCurve &easingCurve)
|
||||||
|
{
|
||||||
|
d->easingCurve = easingCurve;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimeLine::setEasingCurve(QEasingCurve::Type type)
|
||||||
|
{
|
||||||
|
d->easingCurve.setType(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TimeLine::running() const
|
||||||
|
{
|
||||||
|
return d->elapsed != std::chrono::milliseconds::zero()
|
||||||
|
&& d->elapsed != d->duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TimeLine::done() const
|
||||||
|
{
|
||||||
|
return d->done;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimeLine::reset()
|
||||||
|
{
|
||||||
|
d->lastTimestamp = std::nullopt;
|
||||||
|
d->elapsed = std::chrono::milliseconds::zero();
|
||||||
|
d->done = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
TimeLine::RedirectMode TimeLine::sourceRedirectMode() const
|
||||||
|
{
|
||||||
|
return d->sourceRedirectMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimeLine::setSourceRedirectMode(RedirectMode mode)
|
||||||
|
{
|
||||||
|
d->sourceRedirectMode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
TimeLine::RedirectMode TimeLine::targetRedirectMode() const
|
||||||
|
{
|
||||||
|
return d->targetRedirectMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimeLine::setTargetRedirectMode(RedirectMode mode)
|
||||||
|
{
|
||||||
|
d->targetRedirectMode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
TimeLine &TimeLine::operator=(const TimeLine &other)
|
||||||
|
{
|
||||||
|
d = other.d;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace KWin
|
270
src/libkwineffects/timeline.h
Normal file
270
src/libkwineffects/timeline.h
Normal file
|
@ -0,0 +1,270 @@
|
||||||
|
/*
|
||||||
|
SPDX-FileCopyrightText: 2018 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "kwin_export.h"
|
||||||
|
|
||||||
|
#include <QEasingCurve>
|
||||||
|
#include <QSharedDataPointer>
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
|
namespace KWin
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The TimeLine class is a helper for controlling animations.
|
||||||
|
*/
|
||||||
|
class KWIN_EXPORT TimeLine
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Direction of the timeline.
|
||||||
|
*
|
||||||
|
* When the direction of the timeline is Forward, the progress
|
||||||
|
* value will go from 0.0 to 1.0.
|
||||||
|
*
|
||||||
|
* When the direction of the timeline is Backward, the progress
|
||||||
|
* value will go from 1.0 to 0.0.
|
||||||
|
*/
|
||||||
|
enum Direction {
|
||||||
|
Forward,
|
||||||
|
Backward
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new instance of TimeLine.
|
||||||
|
*
|
||||||
|
* @param duration Duration of the timeline, in milliseconds
|
||||||
|
* @param direction Direction of the timeline
|
||||||
|
* @since 5.14
|
||||||
|
*/
|
||||||
|
explicit TimeLine(std::chrono::milliseconds duration = std::chrono::milliseconds(1000),
|
||||||
|
Direction direction = Forward);
|
||||||
|
TimeLine(const TimeLine &other);
|
||||||
|
~TimeLine();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current value of the timeline.
|
||||||
|
*
|
||||||
|
* @since 5.14
|
||||||
|
*/
|
||||||
|
qreal value() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Advances the timeline to the specified @a timestamp.
|
||||||
|
*/
|
||||||
|
void advance(std::chrono::milliseconds timestamp);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of elapsed milliseconds.
|
||||||
|
*
|
||||||
|
* @see setElapsed
|
||||||
|
* @since 5.14
|
||||||
|
*/
|
||||||
|
std::chrono::milliseconds elapsed() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the number of elapsed milliseconds.
|
||||||
|
*
|
||||||
|
* This method overwrites previous value of elapsed milliseconds.
|
||||||
|
* If the new value of elapsed milliseconds is greater or equal
|
||||||
|
* to duration of the timeline, the timeline will be finished, i.e.
|
||||||
|
* proceeding TimeLine::done method calls will return @c true.
|
||||||
|
* Please don't use it. Instead, use TimeLine::update.
|
||||||
|
*
|
||||||
|
* @note The new number of elapsed milliseconds should be a non-negative
|
||||||
|
* number, i.e. it should be greater or equal to 0.
|
||||||
|
*
|
||||||
|
* @param elapsed The new number of elapsed milliseconds
|
||||||
|
* @see elapsed
|
||||||
|
* @since 5.14
|
||||||
|
*/
|
||||||
|
void setElapsed(std::chrono::milliseconds elapsed);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the duration of the timeline.
|
||||||
|
*
|
||||||
|
* @returns Duration of the timeline, in milliseconds
|
||||||
|
* @see setDuration
|
||||||
|
* @since 5.14
|
||||||
|
*/
|
||||||
|
std::chrono::milliseconds duration() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the duration of the timeline.
|
||||||
|
*
|
||||||
|
* In addition to setting new value of duration, the timeline will
|
||||||
|
* try to retarget the number of elapsed milliseconds to match
|
||||||
|
* as close as possible old progress value. If the new duration
|
||||||
|
* is much smaller than old duration, there is a big chance that
|
||||||
|
* the timeline will be finished after setting new duration.
|
||||||
|
*
|
||||||
|
* @note The new duration should be a positive number, i.e. it
|
||||||
|
* should be greater or equal to 1.
|
||||||
|
*
|
||||||
|
* @param duration The new duration of the timeline, in milliseconds
|
||||||
|
* @see duration
|
||||||
|
* @since 5.14
|
||||||
|
*/
|
||||||
|
void setDuration(std::chrono::milliseconds duration);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the direction of the timeline.
|
||||||
|
*
|
||||||
|
* @returns Direction of the timeline(TimeLine::Forward or TimeLine::Backward)
|
||||||
|
* @see setDirection
|
||||||
|
* @see toggleDirection
|
||||||
|
* @since 5.14
|
||||||
|
*/
|
||||||
|
Direction direction() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the direction of the timeline.
|
||||||
|
*
|
||||||
|
* @param direction The new direction of the timeline
|
||||||
|
* @see direction
|
||||||
|
* @see toggleDirection
|
||||||
|
* @since 5.14
|
||||||
|
*/
|
||||||
|
void setDirection(Direction direction);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggles the direction of the timeline.
|
||||||
|
*
|
||||||
|
* If the direction of the timeline was TimeLine::Forward, it becomes
|
||||||
|
* TimeLine::Backward, and vice verca.
|
||||||
|
*
|
||||||
|
* @see direction
|
||||||
|
* @see setDirection
|
||||||
|
* @since 5.14
|
||||||
|
*/
|
||||||
|
void toggleDirection();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the easing curve of the timeline.
|
||||||
|
*
|
||||||
|
* @see setEasingCurve
|
||||||
|
* @since 5.14
|
||||||
|
*/
|
||||||
|
QEasingCurve easingCurve() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets new easing curve.
|
||||||
|
*
|
||||||
|
* @param easingCurve An easing curve to be set
|
||||||
|
* @see easingCurve
|
||||||
|
* @since 5.14
|
||||||
|
*/
|
||||||
|
void setEasingCurve(const QEasingCurve &easingCurve);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets new easing curve by providing its type.
|
||||||
|
*
|
||||||
|
* @param type Type of the easing curve(e.g. QEasingCurve::InCubic, etc)
|
||||||
|
* @see easingCurve
|
||||||
|
* @since 5.14
|
||||||
|
*/
|
||||||
|
void setEasingCurve(QEasingCurve::Type type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the timeline is currently in progress.
|
||||||
|
*
|
||||||
|
* @see done
|
||||||
|
* @since 5.14
|
||||||
|
*/
|
||||||
|
bool running() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the timeline is finished.
|
||||||
|
*
|
||||||
|
* @see reset
|
||||||
|
* @since 5.14
|
||||||
|
*/
|
||||||
|
bool done() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the timeline to initial state.
|
||||||
|
*
|
||||||
|
* @since 5.14
|
||||||
|
*/
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
enum class RedirectMode {
|
||||||
|
Strict,
|
||||||
|
Relaxed
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the redirect mode for the source position.
|
||||||
|
*
|
||||||
|
* The redirect mode controls behavior of the timeline when its direction is
|
||||||
|
* changed at the source position, e.g. what should we do when the timeline
|
||||||
|
* initially goes forward and we change its direction to go backward.
|
||||||
|
*
|
||||||
|
* In the strict mode, the timeline will stop.
|
||||||
|
*
|
||||||
|
* In the relaxed mode, the timeline will go in the new direction. For example,
|
||||||
|
* if the timeline goes forward(from 0 to 1), then with the new direction it
|
||||||
|
* will go backward(from 1 to 0).
|
||||||
|
*
|
||||||
|
* The default is RedirectMode::Relaxed.
|
||||||
|
*
|
||||||
|
* @see targetRedirectMode
|
||||||
|
* @since 5.15
|
||||||
|
*/
|
||||||
|
RedirectMode sourceRedirectMode() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the redirect mode for the source position.
|
||||||
|
*
|
||||||
|
* @param mode The new mode.
|
||||||
|
* @since 5.15
|
||||||
|
*/
|
||||||
|
void setSourceRedirectMode(RedirectMode mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the redirect mode for the target position.
|
||||||
|
*
|
||||||
|
* The redirect mode controls behavior of the timeline when its direction is
|
||||||
|
* changed at the target position.
|
||||||
|
*
|
||||||
|
* In the strict mode, subsequent update calls won't have any effect on the
|
||||||
|
* current value of the timeline.
|
||||||
|
*
|
||||||
|
* In the relaxed mode, the timeline will go in the new direction.
|
||||||
|
*
|
||||||
|
* The default is RedirectMode::Strict.
|
||||||
|
*
|
||||||
|
* @see sourceRedirectMode
|
||||||
|
* @since 5.15
|
||||||
|
*/
|
||||||
|
RedirectMode targetRedirectMode() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the redirect mode for the target position.
|
||||||
|
*
|
||||||
|
* @param mode The new mode.
|
||||||
|
* @since 5.15
|
||||||
|
*/
|
||||||
|
void setTargetRedirectMode(RedirectMode mode);
|
||||||
|
|
||||||
|
TimeLine &operator=(const TimeLine &other);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns a value between 0 and 1 defining the progress of the timeline
|
||||||
|
*
|
||||||
|
* @since 5.23
|
||||||
|
*/
|
||||||
|
qreal progress() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
class Data;
|
||||||
|
QSharedDataPointer<Data> d;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace KWin
|
|
@ -9,6 +9,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "libkwineffects/kwineffects.h"
|
#include "libkwineffects/kwineffects.h"
|
||||||
#include "libkwineffects/kwinoffscreeneffect.h"
|
#include "libkwineffects/kwinoffscreeneffect.h"
|
||||||
|
#include "libkwineffects/timeline.h"
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
namespace KWin
|
namespace KWin
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
// kwineffects
|
// kwineffects
|
||||||
#include "libkwineffects/kwineffects.h"
|
#include "libkwineffects/kwineffects.h"
|
||||||
|
#include "libkwineffects/timeline.h"
|
||||||
|
|
||||||
namespace KWin
|
namespace KWin
|
||||||
{
|
{
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
// kwineffects
|
// kwineffects
|
||||||
#include "libkwineffects/kwineffects.h"
|
#include "libkwineffects/kwineffects.h"
|
||||||
|
#include "libkwineffects/timeline.h"
|
||||||
|
|
||||||
namespace KWin
|
namespace KWin
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "libkwineffects/kwineffects.h"
|
#include "libkwineffects/kwineffects.h"
|
||||||
|
#include "libkwineffects/timeline.h"
|
||||||
|
|
||||||
namespace KWin
|
namespace KWin
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "libkwineffects/kwinoffscreeneffect.h"
|
#include "libkwineffects/kwinoffscreeneffect.h"
|
||||||
|
#include "libkwineffects/timeline.h"
|
||||||
|
|
||||||
namespace KWin
|
namespace KWin
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include "core/output.h"
|
#include "core/output.h"
|
||||||
#include "libkwineffects/kwineffects.h"
|
#include "libkwineffects/kwineffects.h"
|
||||||
|
#include "libkwineffects/timeline.h"
|
||||||
|
|
||||||
namespace KWin
|
namespace KWin
|
||||||
{
|
{
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
// kwineffects
|
// kwineffects
|
||||||
#include "libkwineffects/kwineffects.h"
|
#include "libkwineffects/kwineffects.h"
|
||||||
|
#include "libkwineffects/timeline.h"
|
||||||
|
|
||||||
namespace KWin
|
namespace KWin
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
// Include with base class for effects.
|
// Include with base class for effects.
|
||||||
#include "libkwineffects/kwineffects.h"
|
#include "libkwineffects/kwineffects.h"
|
||||||
|
#include "libkwineffects/timeline.h"
|
||||||
|
|
||||||
namespace KWin
|
namespace KWin
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "libkwineffects/kwineffects.h"
|
#include "libkwineffects/kwineffects.h"
|
||||||
|
#include "libkwineffects/timeline.h"
|
||||||
|
|
||||||
namespace KWin
|
namespace KWin
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue