soui 5.0.0.1
Soui5 Doc
 
Loading...
Searching...
No Matches
TypeEvaluator.h
Go to the documentation of this file.
1/**
2 * @file TypeEvaluator.h
3 * @brief Interface for use with the ValueAnimator::setEvaluator(TypeEvaluator) function.
4 * @details Evaluators allow developers to create animations on arbitrary property types,
5 * by allowing them to supply custom evaluators for types that are not automatically
6 * understood and used by the animation system.
7 *
8 * @see ValueAnimator::setEvaluator(TypeEvaluator)
9 */
10
11#ifndef __TYPEEVALUATOR__H__
12#define __TYPEEVALUATOR__H__
13
14#include <math.h>
15#include <helper/obj-ref-impl.hpp>
16#include <helper/SColor.h>
17
18SNSBEGIN
19
20/**
21 * @brief Template function for linearly interpolating values.
22 * @tparam T The type of the values to interpolate.
23 * @param fraction The fraction from the starting to the ending values.
24 * @param start The starting value.
25 * @param end The ending value.
26 * @return The linearly interpolated value.
27 */
28template <typename T>
29inline T Evaluate(float fraction, const T &start, const T &end)
30{
31 return (T)(start + fraction * (end - start));
32}
33
34/**
35 * @class TypeEvaluator
36 * @brief Template class for evaluating interpolated values between a start and end value.
37 * @tparam T The type of the values to evaluate.
38 */
39template <typename T>
40class TypeEvaluator : public TObjRefImpl<IObjRef> {
41 public:
42 /**
43 * @brief Starting value for the interpolation.
44 */
46
47 /**
48 * @brief Ending value for the interpolation.
49 */
51
52 public:
53 /**
54 * @brief Default constructor.
55 */
57 {
58 }
59
60 /**
61 * @brief Constructor initializing the start and end values.
62 * @param start The starting value.
63 * @param end The ending value.
64 */
65 TypeEvaluator(T start, T end)
66 {
67 mStart = start;
68 mEnd = end;
69 }
70
71 /**
72 * @brief Sets the range for the interpolation.
73 * @param start The starting value.
74 * @param end The ending value.
75 */
76 void setRange(T start, T end)
77 {
78 mStart = start;
79 mEnd = end;
80 }
81
82 /**
83 * @brief Copies the properties of another TypeEvaluator.
84 * @param src The source TypeEvaluator to copy from.
85 */
86 void copy(const TypeEvaluator<T> *src)
87 {
88 mStart = src->mStart;
89 mEnd = src->mEnd;
90 }
91
92 /**
93 * @brief Evaluates the interpolated value between the start and end values.
94 * @param fraction The fraction from the starting to the ending values.
95 * @return The linearly interpolated value.
96 */
97 T evaluate(float fraction) const
98 {
99 return Evaluate(fraction, mStart, mEnd);
100 }
101};
102
103/**
104 * @class TypeEvaluator<COLORREF>
105 * @brief Specialized class for evaluating interpolated values between two COLORREF values.
106 */
107template <>
108class TypeEvaluator<COLORREF> {
109 public:
110 /**
111 * @brief Starting alpha value.
112 */
113 float startA;
114
115 /**
116 * @brief Starting red value.
117 */
118 float startR;
119
120 /**
121 * @brief Starting green value.
122 */
123 float startG;
124
125 /**
126 * @brief Starting blue value.
127 */
128 float startB;
129
130 /**
131 * @brief Ending alpha value.
132 */
133 float endA;
134
135 /**
136 * @brief Ending red value.
137 */
138 float endR;
139
140 /**
141 * @brief Ending green value.
142 */
143 float endG;
144
145 /**
146 * @brief Ending blue value.
147 */
148 float endB;
149
150 public:
151 /**
152 * @brief Constructor initializing the start and end COLORREF values.
153 * @param start The starting COLORREF value.
154 * @param end The ending COLORREF value.
155 */
156 TypeEvaluator(COLORREF start, COLORREF end)
157 {
158 setStart(start);
159 setEnd(end);
160 }
161
162 /**
163 * @brief Sets the starting COLORREF value.
164 * @param start The starting COLORREF value.
165 */
166 void setStart(COLORREF start)
167 {
168 startA = GetAValue(start) / 255.0f;
169 startR = GetRValue(start) / 255.0f;
170 startG = GetGValue(start) / 255.0f;
171 startB = GetBValue(start) / 255.0f;
172 // Convert from sRGB to linear
173 startR = (float)pow(startR, 2.2f);
174 startG = (float)pow(startG, 2.2f);
175 startB = (float)pow(startB, 2.2f);
176 }
177
178 /**
179 * @brief Sets the ending COLORREF value.
180 * @param end The ending COLORREF value.
181 */
182 void setEnd(COLORREF end)
183 {
184 endA = GetAValue(end) / 255.0f;
185 endR = GetRValue(end) / 255.0f;
186 endG = GetGValue(end) / 255.0f;
187 endB = GetBValue(end) / 255.0f;
188 // Convert from sRGB to linear
189 endR = (float)pow(endR, 2.2f);
190 endG = (float)pow(endG, 2.2f);
191 endB = (float)pow(endB, 2.2f);
192 }
193
194 /**
195 * @brief Rounds a float value to the nearest integer.
196 * @param v The float value to round.
197 * @return The rounded integer value.
198 */
199 int round(float v) const
200 {
201 return (int)floor(v + 0.5f);
202 }
203
204 /**
205 * @brief Evaluates the interpolated COLORREF value between the start and end values.
206 * @param fraction The fraction from the starting to the ending values.
207 * @return The interpolated COLORREF value.
208 */
209 COLORREF evaluate(float fraction) const
210 {
211 // Compute the interpolated color in linear space
212 float a = startA + fraction * (endA - startA);
213 float r = startR + fraction * (endR - startR);
214 float g = startG + fraction * (endG - startG);
215 float b = startB + fraction * (endB - startB);
216
217 // Convert back to sRGB in the [0..255] range
218 a = a * 255.0f;
219 r = (float)pow(r, 1.0f / 2.2f) * 255.0f;
220 g = (float)pow(g, 1.0f / 2.2f) * 255.0f;
221 b = (float)pow(b, 1.0f / 2.2f) * 255.0f;
222
223 return RGBA(round(r), round(g), round(b), round(a));
224 }
225
226 /**
227 * @brief Copies the properties of another TypeEvaluator<COLORREF>.
228 * @param src The source TypeEvaluator<COLORREF> to copy from.
229 */
231 {
232 startA = src->startA;
233 startR = src->startR;
234 startG = src->startG;
235 startB = src->startB;
236
237 endA = src->endA;
238 endR = src->endR;
239 endG = src->endG;
240 endB = src->endB;
241 }
242
243 /**
244 * @brief Sets the range for the interpolation.
245 * @param from The starting COLORREF value.
246 * @param to The ending COLORREF value.
247 */
248 void setRange(COLORREF from, COLORREF to)
249 {
250 setStart(from);
251 setEnd(to);
252 }
253};
254
255/**
256 * @brief Template specialization for linearly interpolating RECT values.
257 * @param fraction The fraction from the starting to the ending values.
258 * @param mStart The starting RECT value.
259 * @param mEnd The ending RECT value.
260 * @return The linearly interpolated RECT value.
261 */
262template <>
263inline RECT Evaluate(float fraction, const RECT &mStart, const RECT &mEnd)
264{
265 RECT ret;
266 ret.left = Evaluate(fraction, mStart.left, mEnd.left);
267 ret.top = Evaluate(fraction, mStart.top, mEnd.top);
268 ret.right = Evaluate(fraction, mStart.right, mEnd.right);
269 ret.bottom = Evaluate(fraction, mStart.bottom, mEnd.bottom);
270 return ret;
271}
272
273/**
274 * @brief Template specialization for linearly interpolating POINT values.
275 * @param fraction The fraction from the starting to the ending values.
276 * @param mStart The starting POINT value.
277 * @param mEnd The ending POINT value.
278 * @return The linearly interpolated POINT value.
279 */
280template <>
281inline POINT Evaluate(float fraction, const POINT &mStart, const POINT &mEnd)
282{
283 POINT ret;
284 ret.x = Evaluate(fraction, mStart.x, mEnd.x);
285 ret.y = Evaluate(fraction, mStart.y, mEnd.y);
286 return ret;
287}
288
289/**
290 * @brief Template specialization for linearly interpolating SIZE values.
291 * @param fraction The fraction from the starting to the ending values.
292 * @param mStart The starting SIZE value.
293 * @param mEnd The ending SIZE value.
294 * @return The linearly interpolated SIZE value.
295 */
296template <>
297inline SIZE Evaluate(float fraction, const SIZE &mStart, const SIZE &mEnd)
298{
299 SIZE ret;
300 ret.cx = Evaluate(fraction, mStart.cx, mEnd.cx);
301 ret.cy = Evaluate(fraction, mStart.cy, mEnd.cy);
302 return ret;
303}
304
305SNSEND
306
307#endif // __TYPEEVALUATOR__H__
SNSBEGIN T Evaluate(float fraction, const T &start, const T &end)
Template function for linearly interpolating values.
void setStart(COLORREF start)
Sets the starting COLORREF value.
float endB
Ending blue value.
float endA
Ending alpha value.
float startA
Starting alpha value.
int round(float v) const
Rounds a float value to the nearest integer.
void setEnd(COLORREF end)
Sets the ending COLORREF value.
void copy(const TypeEvaluator< COLORREF > *src)
Copies the properties of another TypeEvaluator<COLORREF>.
float startR
Starting red value.
COLORREF evaluate(float fraction) const
Evaluates the interpolated COLORREF value between the start and end values.
void setRange(COLORREF from, COLORREF to)
Sets the range for the interpolation.
float startB
Starting blue value.
float startG
Starting green value.
float endR
Ending red value.
float endG
Ending green value.
TypeEvaluator(COLORREF start, COLORREF end)
Constructor initializing the start and end COLORREF values.
T mEnd
Ending value for the interpolation.
TypeEvaluator(T start, T end)
Constructor initializing the start and end values.
T mStart
Starting value for the interpolation.
void setRange(T start, T end)
Sets the range for the interpolation.
void copy(const TypeEvaluator< T > *src)
Copies the properties of another TypeEvaluator.
T evaluate(float fraction) const
Evaluates the interpolated value between the start and end values.
TypeEvaluator()
Default constructor.