1// Aseprite UI Library
2// Copyright (C) 2019 Igara Studio S.A.
3// Copyright (C) 2001-2016 David Capello
4//
5// This file is released under the terms of the MIT license.
6// Read LICENSE.txt for more information.
7
8#ifndef UI_ANIMATED_WIDGET_H_INCLUDED
9#define UI_ANIMATED_WIDGET_H_INCLUDED
10#pragma once
11
12#include "obs/connection.h"
13#include "ui/timer.h"
14
15#include <cmath>
16
17namespace ui {
18
19 class AnimatedWidget {
20 public:
21 AnimatedWidget()
22 : m_timer(1000/60)
23 , m_animation(0) {
24 m_scopedConn = m_timer.Tick.connect(&AnimatedWidget::onTick, this);
25 }
26
27 ~AnimatedWidget() {
28 m_timer.stop();
29 }
30
31 // For each animation frame
32 virtual void onAnimationStart() { }
33 virtual void onAnimationStop(int animation) { }
34 virtual void onAnimationFrame() { }
35
36 protected:
37 void startAnimation(int animation, int lifespan) {
38 // Stop previous animation
39 if (m_animation)
40 stopAnimation();
41
42 m_animation = animation;
43 m_animationTime = 0;
44 m_animationLifespan = lifespan;
45 m_timer.start();
46
47 onAnimationStart();
48 }
49
50 void stopAnimation() {
51 int animation = m_animation;
52 m_animation = 0;
53 m_timer.stop();
54
55 onAnimationStop(animation);
56 }
57
58 int animation() const {
59 return m_animation;
60 }
61
62 double animationTime() const {
63 return double(m_animationTime) / double(m_animationLifespan);
64 }
65
66 double ease(double t) {
67 return (1.0 - std::pow(1.0 - t, 2));
68 }
69
70 double inbetween(double x0, double x1, double t) {
71 return x0 + (x1-x0)*ease(t);
72 }
73
74 private:
75 void onTick() {
76 if (m_animation) {
77 if (m_animationTime == m_animationLifespan)
78 stopAnimation();
79 else
80 ++m_animationTime;
81
82 onAnimationFrame();
83 }
84 }
85
86 ui::Timer m_timer;
87 int m_animation;
88 int m_animationTime;
89 int m_animationLifespan;
90 obs::scoped_connection m_scopedConn;
91 };
92
93} // namespace ui
94
95#endif
96