initial commit
[ld42_outofspace] / src / goatkit / boolanm.cc
1 /*
2 GoatKit - a themable/animated widget toolkit for games
3 Copyright (C) 2014-2015 John Tsiombikas <nuclear@member.fsf.org>
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18 #include "boolanm.h"
19
20 static long default_get_msec();
21
22 BoolAnim::BoolAnim(bool st)
23 {
24         set(st);
25         trans_start = 0;
26         trans_dur = 500;
27         get_msec = default_get_msec;
28 }
29
30 void BoolAnim::update(long tm) const
31 {
32         if(trans_dir == 0.0) return;
33
34         float dt = (tm - trans_start) / 1000.0;
35         float t = dt / (trans_dur / 1000.0);
36
37         if(trans_dir > 0.0) {
38                 value = t;
39         } else {
40                 value = 1.0 - t;
41         }
42
43         if(value < 0.0) {
44                 value = 0.0;
45                 trans_dir = 0.0;
46         } else if(value > 1.0) {
47                 value = 1.0;
48                 trans_dir = 0.0;
49         }
50 }
51
52 void BoolAnim::set_transition_duration(long dur)
53 {
54         trans_dur = dur;
55 }
56
57 long BoolAnim::get_transition_duration() const
58 {
59         return trans_dur;
60 }
61
62 void BoolAnim::set_time_callback(long (*time_func)())
63 {
64         get_msec = time_func;
65 }
66
67 void BoolAnim::set(bool st)
68 {
69         value = st ? 1.0 : 0.0;
70         trans_dir = 0.0;
71 }
72
73 void BoolAnim::change(bool st)
74 {
75         change(st, get_msec());
76 }
77
78 void BoolAnim::change(bool st, long tm)
79 {
80         trans_dir = st ? 1.0 : -1.0;
81         trans_start = tm;
82 }
83
84 bool BoolAnim::get_state() const
85 {
86         return get_state(get_msec());
87 }
88
89 bool BoolAnim::get_state(long tm) const
90 {
91         update(tm);
92
93         // if we're not in transition use the value (should be 0 or 1)
94         if(trans_dir == 0.0) {
95                 return value > 0.5;
96         }
97
98         // if we're in transition base it on the direction of the transition
99         return trans_dir > 0.0;
100 }
101
102 float BoolAnim::get_value() const
103 {
104         return get_value(get_msec());
105 }
106
107 float BoolAnim::get_value(long tm) const
108 {
109         update(tm);
110         return value;
111 }
112
113 float BoolAnim::get_dir() const
114 {
115         return get_dir(get_msec());
116 }
117
118 float BoolAnim::get_dir(long tm) const
119 {
120         update(tm);
121         return trans_dir;
122 }
123
124 BoolAnim::operator bool() const
125 {
126         return get_state();
127 }
128
129 BoolAnim::operator float() const
130 {
131         return get_value();
132 }
133
134 #ifdef WIN32
135 #include <windows.h>
136
137 static long default_get_msec()
138 {
139         return GetTickCount();
140 }
141 #else
142 #include <sys/time.h>
143
144 static long default_get_msec()
145 {
146         static struct timeval tv0;
147         struct timeval tv;
148
149         gettimeofday(&tv, 0);
150         if(tv0.tv_sec == 0 && tv0.tv_usec == 0) {
151                 tv0 = tv;
152                 return 0;
153         }
154         return (tv.tv_sec - tv0.tv_sec) * 1000 + (tv.tv_usec - tv0.tv_usec) / 1000;
155 }
156 #endif