1 #include <math.h>
2 #include "studiox_includes.h"
3 #include "easing_function_select_dlg.h"
4
5
6 // easing_function_select_dlg dialog
7
8 #define ANIMATION_TOTAL_STEP 50
9 #define ANIMATION_TIMER_ID 1024
10 #define ANIMATION_BOX_WIDTH 30
11 #define ANIMATION_BOX_HEIGHT 16
12 #define ANIMATION_DOT_RADIUS 10
13
14
15 enum easing_function_select_dlg_test_commands{
16 TEST_SELECT_EASING_FUNCTION = 1,
17 TEST_SAVE_EASING_FUNCTION_SELECT,
18 TEST_CANCEL_EASING_FUNCTION_SELECT
19 };
20
21 STRING_VAL_PAIR easing_function_list[] = {
22 { _T("back ease in"), GX_ANIMATION_BACK_EASE_IN },
23 { _T("back ease out"), GX_ANIMATION_BACK_EASE_OUT },
24 { _T("back ease in out"), GX_ANIMATION_BACK_EASE_IN_OUT },
25 { _T("bounce ease in"), GX_ANIMATION_BOUNCE_EASE_IN },
26 { _T("bounce ease out"), GX_ANIMATION_BOUNCE_EASE_OUT },
27 { _T("bounce ease in out"), GX_ANIMATION_BOUNCE_EASE_IN_OUT },
28 { _T("circ ease in"), GX_ANIMATION_CIRC_EASE_IN },
29 { _T("circ ease out"), GX_ANIMATION_CIRC_EASE_OUT },
30 { _T("circ ease in out"), GX_ANIMATION_CIRC_EASE_IN_OUT },
31 { _T("cubic ease in"), GX_ANIMATION_CUBIC_EASE_IN },
32 { _T("cubic ease out"), GX_ANIMATION_CUBIC_EASE_OUT },
33 { _T("cubic ease in out"), GX_ANIMATION_CUBIC_EASE_IN_OUT },
34 { _T("elastic ease in"), GX_ANIMATION_ELASTIC_EASE_IN },
35 { _T("elastic ease out"), GX_ANIMATION_ELASTIC_EASE_OUT },
36 { _T("elastic ease in out"), GX_ANIMATION_ELASTIC_EASE_IN_OUT },
37 { _T("expo ease in"), GX_ANIMATION_EXPO_EASE_IN },
38 { _T("expo ease out"), GX_ANIMATION_EXPO_EASE_OUT },
39 { _T("expo ease in out"), GX_ANIMATION_EXPO_EASE_IN_OUT },
40 { _T("quad ease in"), GX_ANIMATION_QUAD_EASE_IN },
41 { _T("quad ease out"), GX_ANIMATION_QUAD_EASE_OUT },
42 { _T("quad ease in out"), GX_ANIMATION_QUAD_EASE_IN_OUT },
43 { _T("quart ease in"), GX_ANIMATION_QUART_EASE_IN },
44 { _T("quart ease out"), GX_ANIMATION_QUART_EASE_OUT },
45 { _T("quart ease in out"), GX_ANIMATION_QUART_EASE_IN_OUT },
46 { _T("quint ease in"), GX_ANIMATION_QUINT_EASE_IN },
47 { _T("quint ease out"), GX_ANIMATION_QUINT_EASE_OUT },
48 { _T("quint ease in out"), GX_ANIMATION_QUINT_EASE_IN_OUT },
49 { _T("sine ease in"), GX_ANIMATION_SINE_EASE_IN },
50 { _T("sine ease out"), GX_ANIMATION_SINE_EASE_OUT },
51 { _T("sine ease in out"), GX_ANIMATION_SINE_EASE_IN_OUT },
52 { _T(""), 0}
53 };
54
IMPLEMENT_DYNAMIC(easing_function_select_dlg,express_dialog)55 IMPLEMENT_DYNAMIC(easing_function_select_dlg, express_dialog)
56
57 BEGIN_MESSAGE_MAP(easing_function_select_dlg, express_dialog)
58 ON_CBN_SELCHANGE(IDC_EASING_FUNC_COMBO, OnSelecteEasingFuncCombo)
59 ON_WM_PAINT()
60 ON_WM_ERASEBKGND()
61 ON_WM_TIMER()
62 ON_BN_CLICKED(IDC_ANIMATION_START, &easing_function_select_dlg::OnAnimationStart)
63 ON_MESSAGE(STUDIO_TEST, &easing_function_select_dlg::OnTestMessage)
64 END_MESSAGE_MAP()
65
66 ///////////////////////////////////////////////////////////////////////////////
67 easing_function_select_dlg::easing_function_select_dlg(int easing_function_id, CWnd* pParent /*=NULL*/)
68 : express_dialog(easing_function_select_dlg::IDD, pParent)
69 {
70 SetTitleText("Select Easing Function");
71 IconId = IDB_CONFIGURE_PROJECTS;
72 mEasingFuncId = easing_function_id;
73
74 mWaveRect.left = 0;
75 mWaveRect.right = 0;
76 mWaveRect.top = 0;
77 mWaveRect.bottom = 0;
78 mAnimationStep = 0;
79
80 int dpi = GetSystemDPI();
81 mAnimationBoxSize.cx = MulDiv(ANIMATION_BOX_WIDTH, dpi, DEFAULT_DPI_96);
82 mAnimationBoxSize.cy = MulDiv(ANIMATION_BOX_HEIGHT, dpi, DEFAULT_DPI_96);
83
84 mAnimationDotRadius = MulDiv(ANIMATION_DOT_RADIUS, dpi, DEFAULT_DPI_96);
85 }
86
87 ///////////////////////////////////////////////////////////////////////////////
~easing_function_select_dlg()88 easing_function_select_dlg::~easing_function_select_dlg()
89 {
90 }
91
92 ///////////////////////////////////////////////////////////////////////////////
GetEasingFuncId(CString type_name)93 int easing_function_select_dlg::GetEasingFuncId(CString type_name)
94 {
95 return FindPairVal(easing_function_list, type_name);
96 }
97
98 ///////////////////////////////////////////////////////////////////////////////
GetEasingFuncIdName(int type)99 CString easing_function_select_dlg::GetEasingFuncIdName(int type)
100 {
101 return FindPairString(easing_function_list, type);
102 }
103
104 ///////////////////////////////////////////////////////////////////////////////
DoDataExchange(CDataExchange * pDX)105 void easing_function_select_dlg::DoDataExchange(CDataExchange* pDX)
106 {
107 express_dialog::DoDataExchange(pDX);
108 DDX_Control(pDX, IDC_EASING_FUNC_COMBO, mEasingFuncCombo);
109 DDX_Control(pDX, IDC_ANIMATION_STATUS, mAnimationStatus);
110
111 if (!pDX->m_bSaveAndValidate)
112 {
113 mAnimationStatus.SetWindowTextW(L"");
114 SetLiveRegion(mAnimationStatus.GetSafeHwnd());
115 }
116 }
117
118 ///////////////////////////////////////////////////////////////////////////////
OnInitDialog()119 BOOL easing_function_select_dlg::OnInitDialog()
120 {
121 express_dialog::OnInitDialog();
122
123 AddCancelButton();
124 AddSaveButton();
125
126 STRING_VAL_PAIR *current = easing_function_list;
127 int index;
128 int sel_index = -1;
129
130 while (current->name.GetLength())
131 {
132 index = mEasingFuncCombo.AddString(current->name);
133 mEasingFuncCombo.SetItemData(index, current->val);
134 if (current->val == mEasingFuncId)
135 {
136 sel_index = index;
137 }
138 current++;
139 }
140
141 if (sel_index >= 0)
142 {
143 mEasingFuncCombo.SetCurSel(sel_index);
144 }
145 mEasingFuncCombo.InsertString(0, _T("None"));
146
147 if (sel_index < 0)
148 {
149 mEasingFuncCombo.SetCurSel(0);
150 }
151
152 return TRUE;
153 }
154
155 ///////////////////////////////////////////////////////////////////////////////
OnPaint()156 void easing_function_select_dlg::OnPaint()
157 {
158 CPaintDC dc(this);
159 CRect rect;
160
161 GetDlgItem(IDC_ANIMATION_START)->GetWindowRect(&rect);
162 ScreenToClient(&rect);
163 mWaveRect.top = rect.bottom + (mAnimationBoxSize.cy << 2);
164
165 mAnimationStatus.GetWindowRect(&rect);
166 ScreenToClient(&rect);
167 mWaveRect.bottom = rect.top - (mAnimationBoxSize.cy << 2);
168 mWaveRect.left = rect.left;
169 mWaveRect.right = rect.right;
170
171 mAnimationRect = mWaveRect;
172 mAnimationRect.left -= (mAnimationBoxSize.cx * 3 / 2) + 1;
173 mAnimationRect.right += (mAnimationDotRadius / 2) + 1;
174 mAnimationRect.top -= (mAnimationBoxSize.cy << 2);
175 mAnimationRect.bottom += (mAnimationBoxSize.cy << 2);
176
177 CDC dcMem;
178 HBITMAP hbmMem;
179 HANDLE hOld;
180
181 GetClientRect(&rect);
182
183 /* Flush canvas memory to off-screen DC. */
184 dcMem.CreateCompatibleDC(&dc);
185 hbmMem = CreateCompatibleBitmap(dc, rect.Width(), rect.Height());
186 hOld = SelectObject(dcMem, hbmMem);
187
188 dcMem.FillSolidRect(rect, GetSysColor(COLOR_3DFACE));
189
190 Graphics g(dcMem);
191
192 Color color;
193 color.SetFromCOLORREF(GetSysColor(COLOR_WINDOWTEXT));
194 Pen pen(color);
195
196 g.DrawLine(&pen, mWaveRect.left, mWaveRect.top, mWaveRect.left, mWaveRect.bottom);
197 g.DrawLine(&pen, mWaveRect.left, mWaveRect.bottom, mWaveRect.right, mWaveRect.bottom);
198
199 DrawEasingCurve(g);
200
201 PaintTitleAndStatusBar(&dcMem);
202
203 /* Transfer the off-screen DC to the screen. */
204 BitBlt(dc, 0, 0, rect.Width(), rect.Height(), dcMem, 0, 0, SRCCOPY);
205
206 /* Free-up the off-screen DC. */
207 SelectObject(dcMem, hOld);
208 DeleteObject(hbmMem);
209 DeleteDC(dcMem);
210 }
211
212 ///////////////////////////////////////////////////////////////////////////////
OnEraseBkgnd(CDC * pDC)213 BOOL easing_function_select_dlg::OnEraseBkgnd(CDC* pDC)
214 {
215 return GX_FALSE;
216 }
217
218 ///////////////////////////////////////////////////////////////////////////////
OnTimer(UINT_PTR nIDEvent)219 void easing_function_select_dlg::OnTimer(UINT_PTR nIDEvent)
220 {
221 if (nIDEvent == ANIMATION_TIMER_ID)
222 {
223 mAnimationStep++;
224
225 CString status("");
226 if (mAnimationStep == 1)
227 {
228 if (mEasingFuncId)
229 {
230 status = GetEasingFuncIdName(mEasingFuncId);
231 }
232 else
233 {
234 status = L"linear";
235 }
236
237 status.Append(L" animation is started!");
238 }
239 else if (mAnimationStep == ANIMATION_TOTAL_STEP)
240 {
241 if (mEasingFuncId)
242 {
243 status = GetEasingFuncIdName(mEasingFuncId);
244 }
245 else
246 {
247 status = L"linear";
248 }
249
250 status.Append(L" animation is completed!");
251 KillTimer(ANIMATION_TIMER_ID);
252 }
253
254 if (!status.IsEmpty())
255 {
256 mAnimationStatus.SetWindowTextW(status);
257
258 // Raise a UIA LiveRegionChanged
259 // event so that a screen reader is made aware of a change to the LiveRegion.
260 // Make sure the updated text is set on the label before making this call.
261 mAnimationStatus.NotifyWinEvent(
262 EVENT_OBJECT_LIVEREGIONCHANGED,
263 OBJID_CLIENT,
264 CHILDID_SELF);
265 }
266
267 InvalidateRect(&mAnimationRect);
268 }
269 }
270
271 ///////////////////////////////////////////////////////////////////////////////
OnAnimationStart()272 void easing_function_select_dlg::OnAnimationStart()
273 {
274 mAnimationStep = 0;
275 SetTimer(ANIMATION_TIMER_ID, USER_TIMER_MINIMUM, GX_NULL);
276 }
277
278 ///////////////////////////////////////////////////////////////////////////////
BackEaseIn(float t,float d)279 float easing_function_select_dlg::BackEaseIn(float t, float d)
280 {
281 t /= d;
282 return (float)(t *t*(2.70158 * t - 1.70158));
283 }
284
285 ///////////////////////////////////////////////////////////////////////////////
BackEaseOut(float t,float d)286 float easing_function_select_dlg::BackEaseOut(float t, float d)
287 {
288 t = t / d - 1;
289 return (float)(t * t * (2.70158 * t + 1.70158) + 1);
290 }
291
292 ///////////////////////////////////////////////////////////////////////////////
BackEaseInOut(float t,float d)293 float easing_function_select_dlg::BackEaseInOut(float t, float d)
294 {
295 t = (2 * t / d);
296
297 if (t < 1)
298 {
299 return (float)(t * t * (3.5949 * t - 2.5949) / 2);
300 }
301 else
302 {
303 t -= 2;
304 return (float)(t * t * (3.5949 * t + 2.5949) / 2 + 1);
305 }
306 }
307
308 ///////////////////////////////////////////////////////////////////////////////
BounceEaseIn(float t,float d)309 float easing_function_select_dlg::BounceEaseIn(float t, float d)
310 {
311 return (float)(1 - BounceEaseOut(d - t, d));
312 }
313
314 ///////////////////////////////////////////////////////////////////////////////
BounceEaseOut(float t,float d)315 float easing_function_select_dlg::BounceEaseOut(float t, float d)
316 {
317 t /= d;
318 if (t < 0.363)
319 {
320 return (float)(7.5625 * t * t);
321 }
322 else if (t < 0.727)
323 {
324 t -= (float)0.545;
325 return (float)(7.5625 * t * t + 0.75);
326 }
327 else if (t < 0.909)
328 {
329 t -= (float)0.818;
330 return (float)(7.5625 * t * t + 0.9375);
331 }
332 else
333 {
334 t -= (float)0.9545;
335 return (float)(7.5625 * t * t + 0.984375);
336 }
337
338 }
339
340 ///////////////////////////////////////////////////////////////////////////////
BounceEaseInOut(float t,float d)341 float easing_function_select_dlg::BounceEaseInOut(float t, float d)
342 {
343 if (t * 2 < d)
344 {
345 return BounceEaseIn(t * 2, d) / 2;
346 }
347 else
348 {
349 return (BounceEaseOut(t * 2 - d, d) + 1) / 2;
350 }
351 }
352
353 ///////////////////////////////////////////////////////////////////////////////
CircEaseIn(float t,float d)354 float easing_function_select_dlg::CircEaseIn(float t, float d)
355 {
356 t /= d;
357 return (float)(1 - sqrt(1 - t * t));
358 }
359
360 ///////////////////////////////////////////////////////////////////////////////
CircEaseOut(float t,float d)361 float easing_function_select_dlg::CircEaseOut(float t, float d)
362 {
363 t = (t / d) - 1;
364 return (float)(sqrt(1 - t * t));
365 }
366
367 ///////////////////////////////////////////////////////////////////////////////
CircEaseInOut(float t,float d)368 float easing_function_select_dlg::CircEaseInOut(float t, float d)
369 {
370 t = (2 * t / d);
371 if (t < 1)
372 {
373 return (float)((1 - sqrt(1 - t * t)) / 2);
374 }
375 else
376 {
377 t-=2;
378 return (float)((1 + sqrt(1 - t * t)) / 2);
379 }
380 }
381
382 ///////////////////////////////////////////////////////////////////////////////
CubicEaseIn(float t,float d)383 float easing_function_select_dlg::CubicEaseIn(float t, float d)
384 {
385 t /= d;
386
387 return (t * t * t);
388 }
389
390 ///////////////////////////////////////////////////////////////////////////////
CubicEaseOut(float t,float d)391 float easing_function_select_dlg::CubicEaseOut(float t, float d)
392 {
393 t = t / d - 1;
394 return (t * t * t + 1);
395 }
396
397 ///////////////////////////////////////////////////////////////////////////////
CubicEaseInOut(float t,float d)398 float easing_function_select_dlg::CubicEaseInOut(float t, float d)
399 {
400 t = 2 * t / d;
401
402 if (t < 1)
403 {
404 return (t * t * t / 2);
405 }
406 else
407 {
408 t -= 2;
409 return (t * t * t / 2 + 1);
410 }
411 }
412
413 ///////////////////////////////////////////////////////////////////////////////
ElasticEaseIn(float t,float d)414 float easing_function_select_dlg::ElasticEaseIn(float t, float d)
415 {
416 if (t == 0)
417 {
418 return 0;
419 }
420
421 if (t == d)
422 {
423 return 1;
424 }
425
426 t = (t / d) - 1;
427
428 return (float)(-pow(2, 10 * t) * sin(20.93 * t -1.57));
429 }
430
431 ///////////////////////////////////////////////////////////////////////////////
ElasticEaseOut(float t,float d)432 float easing_function_select_dlg::ElasticEaseOut(float t, float d)
433 {
434 if (t == 0)
435 {
436 return 0;
437 }
438
439 if (t == d)
440 {
441 return 1;
442 }
443
444 t /= d;
445 return (float)(pow(2, -10 * t) * sin(20.93 * t - 1.57) + 1);
446 }
447
448 ///////////////////////////////////////////////////////////////////////////////
ElasticEaseInOut(float t,float d)449 float easing_function_select_dlg::ElasticEaseInOut(float t, float d)
450 {
451 if (t == 0)
452 {
453 return 0;
454 }
455
456 t = (2 * t) / d;
457 if (t == 2)
458 {
459 return 1;
460 }
461
462 if (t < 1)
463 {
464 t -= 1;
465 return (float)(-pow(2, 10 * t) * sin(13.96*t - 1.57) / 2);
466 }
467 else
468 {
469 t -= 1;
470 return (float)(pow(2, -10 * t) * sin(13.96*t - 1.57) / 2 + 1);
471 }
472 }
473
474 ///////////////////////////////////////////////////////////////////////////////
ExpoEaseIn(float t,float d)475 float easing_function_select_dlg::ExpoEaseIn(float t, float d)
476 {
477 t /= d;
478 return (float)pow(2, 10 * (t - 1));
479 }
480
481 ///////////////////////////////////////////////////////////////////////////////
ExpoEaseOut(float t,float d)482 float easing_function_select_dlg::ExpoEaseOut(float t, float d)
483 {
484 t /= d;
485 return (float)(1 - pow(2, -10 * t));
486 }
487
488 ///////////////////////////////////////////////////////////////////////////////
ExpoEaseInOut(float t,float d)489 float easing_function_select_dlg::ExpoEaseInOut(float t, float d)
490 {
491 t = 2 * t / d;
492 if (t < 1)
493 {
494 return (float)pow(2, 10 * (t - 1)) / 2;
495 }
496 else
497 {
498 t--;
499 return (float)(1 - pow(2, -10 * t) / 2);
500 }
501 return 0;
502 }
503
504 ///////////////////////////////////////////////////////////////////////////////
QuadEaseInt(float t,float d)505 float easing_function_select_dlg::QuadEaseInt(float t, float d)
506 {
507 t /= d;
508 return t * t;
509 }
510
511 ///////////////////////////////////////////////////////////////////////////////
QuadEaseOut(float t,float d)512 float easing_function_select_dlg::QuadEaseOut(float t, float d)
513 {
514 t /= d;
515 return t * (2 - t);
516 }
517
518 ///////////////////////////////////////////////////////////////////////////////
QuadEaseInOut(float t,float d)519 float easing_function_select_dlg::QuadEaseInOut(float t, float d)
520 {
521 t = (2 * t / d);
522 if (t < 1)
523 {
524 return (t * t / 2);
525 }
526 else
527 {
528 t--;
529 return ((1 - t* (t - 2)) / 2);
530 }
531 }
532
533 ///////////////////////////////////////////////////////////////////////////////
QuartEaseIn(float t,float d)534 float easing_function_select_dlg::QuartEaseIn(float t, float d)
535 {
536 t /= d;
537 return t * t * t * t;
538 }
539
540 ///////////////////////////////////////////////////////////////////////////////
QuartEaseOut(float t,float d)541 float easing_function_select_dlg::QuartEaseOut(float t, float d)
542 {
543 t = t / d - 1;
544 return (1 - t*t*t*t);
545 }
546
547 ///////////////////////////////////////////////////////////////////////////////
QuartEaseInOut(float t,float d)548 float easing_function_select_dlg::QuartEaseInOut(float t, float d)
549 {
550 t = (2 * t / d);
551 if (t < 1)
552 {
553 return t * t * t * t / 2;
554 }
555 else
556 {
557 t -= 2;
558 return (1 - t * t * t * t / 2);
559 }
560 }
561
562 ///////////////////////////////////////////////////////////////////////////////
QuintEaseIn(float t,float d)563 float easing_function_select_dlg::QuintEaseIn(float t, float d)
564 {
565 t /= d;
566 return t * t * t * t * t;
567 }
568
569 ///////////////////////////////////////////////////////////////////////////////
QuintEaseOut(float t,float d)570 float easing_function_select_dlg::QuintEaseOut(float t, float d)
571 {
572 t = (t / d - 1);
573 return (t * t * t * t * t + 1);
574 }
575
576 ///////////////////////////////////////////////////////////////////////////////
QuintEaseInOut(float t,float d)577 float easing_function_select_dlg::QuintEaseInOut(float t, float d)
578 {
579 t = (2 * t / d);
580 if (t < 1)
581 {
582 return t * t * t * t *t / 2;
583 }
584 else
585 {
586 t -= 2;
587 return (t * t* t* t* t / 2 + 1);
588 }
589 }
590
591 ///////////////////////////////////////////////////////////////////////////////
SinEaseIn(float t,float d)592 float easing_function_select_dlg::SinEaseIn(float t, float d)
593 {
594 return (float)(1 - cos(t / d * 1.57));
595 }
596
597 ///////////////////////////////////////////////////////////////////////////////
SinEaseOut(float t,float d)598 float easing_function_select_dlg::SinEaseOut(float t, float d)
599 {
600 return (float)sin(t / d * 1.57);
601 }
602
603 ///////////////////////////////////////////////////////////////////////////////
SinEaseInOut(float t,float d)604 float easing_function_select_dlg::SinEaseInOut(float t, float d)
605 {
606 return (float)((1 - cos(t / d * 3.14)) / 2);
607 }
608
609 ///////////////////////////////////////////////////////////////////////////////
DrawEasingCurve(Graphics & g)610 void easing_function_select_dlg::DrawEasingCurve(Graphics &g)
611 {
612 SolidBrush red_brush(Color(255, 200, 0, 0));
613 REAL x;
614 REAL x1, x2;
615 REAL y1, y2;
616 REAL width = (REAL)mWaveRect.Width();
617 REAL height = (REAL)mWaveRect.Height();
618
619 Color color;
620 color.SetFromCOLORREF(GetSysColor(COLOR_WINDOWTEXT));
621 Pen line_pen(color);
622
623 g.SetSmoothingMode(SmoothingModeAntiAlias);
624
625 switch (mEasingFuncId)
626 {
627 case GX_ANIMATION_BACK_EASE_IN:
628 mpEasingFuncCallback = BackEaseIn;
629 break;
630 case GX_ANIMATION_BACK_EASE_OUT:
631 mpEasingFuncCallback = BackEaseOut;
632 break;
633 case GX_ANIMATION_BACK_EASE_IN_OUT:
634 mpEasingFuncCallback = BackEaseInOut;
635 break;
636 case GX_ANIMATION_BOUNCE_EASE_IN:
637 mpEasingFuncCallback = BounceEaseIn;
638 break;
639 case GX_ANIMATION_BOUNCE_EASE_OUT:
640 mpEasingFuncCallback = BounceEaseOut;
641 break;
642 case GX_ANIMATION_BOUNCE_EASE_IN_OUT:
643 mpEasingFuncCallback = BounceEaseInOut;
644 break;
645 case GX_ANIMATION_CIRC_EASE_IN:
646 mpEasingFuncCallback = CircEaseIn;
647 break;
648 case GX_ANIMATION_CIRC_EASE_OUT:
649 mpEasingFuncCallback = CircEaseOut;
650 break;
651 case GX_ANIMATION_CIRC_EASE_IN_OUT:
652 mpEasingFuncCallback = CircEaseInOut;
653 break;
654 case GX_ANIMATION_CUBIC_EASE_IN:
655 mpEasingFuncCallback = CubicEaseIn;
656 break;
657 case GX_ANIMATION_CUBIC_EASE_OUT:
658 mpEasingFuncCallback = CubicEaseOut;
659 break;
660 case GX_ANIMATION_CUBIC_EASE_IN_OUT:
661 mpEasingFuncCallback = CubicEaseInOut;
662 break;
663 case GX_ANIMATION_ELASTIC_EASE_IN:
664 mpEasingFuncCallback = ElasticEaseIn;
665 break;
666 case GX_ANIMATION_ELASTIC_EASE_OUT:
667 mpEasingFuncCallback = ElasticEaseOut;
668 break;
669 case GX_ANIMATION_ELASTIC_EASE_IN_OUT:
670 mpEasingFuncCallback = ElasticEaseInOut;
671 break;
672 case GX_ANIMATION_EXPO_EASE_IN:
673 mpEasingFuncCallback = ExpoEaseIn;
674 break;
675 case GX_ANIMATION_EXPO_EASE_OUT:
676 mpEasingFuncCallback = ExpoEaseOut;
677 break;
678 case GX_ANIMATION_EXPO_EASE_IN_OUT:
679 mpEasingFuncCallback = ExpoEaseInOut;
680 break;
681 case GX_ANIMATION_QUAD_EASE_IN:
682 mpEasingFuncCallback = QuadEaseInt;
683 break;
684 case GX_ANIMATION_QUAD_EASE_OUT:
685 mpEasingFuncCallback = QuadEaseOut;
686 break;
687 case GX_ANIMATION_QUAD_EASE_IN_OUT:
688 mpEasingFuncCallback = QuadEaseInOut;
689 break;
690 case GX_ANIMATION_QUART_EASE_IN:
691 mpEasingFuncCallback = QuartEaseIn;
692 break;
693 case GX_ANIMATION_QUART_EASE_OUT:
694 mpEasingFuncCallback = QuartEaseOut;
695 break;
696 case GX_ANIMATION_QUART_EASE_IN_OUT:
697 mpEasingFuncCallback = QuartEaseInOut;
698 break;
699 case GX_ANIMATION_QUINT_EASE_IN:
700 mpEasingFuncCallback = QuintEaseIn;
701 break;
702 case GX_ANIMATION_QUINT_EASE_OUT:
703 mpEasingFuncCallback = QuintEaseOut;
704 break;
705 case GX_ANIMATION_QUINT_EASE_IN_OUT:
706 mpEasingFuncCallback = QuintEaseInOut;
707 break;
708 case GX_ANIMATION_SINE_EASE_IN:
709 mpEasingFuncCallback = SinEaseIn;
710 break;
711 case GX_ANIMATION_SINE_EASE_OUT:
712 mpEasingFuncCallback = SinEaseOut;
713 break;
714 case GX_ANIMATION_SINE_EASE_IN_OUT:
715 mpEasingFuncCallback = SinEaseInOut;
716 break;
717 default:
718 mpEasingFuncCallback = GX_NULL;
719 break;
720 }
721
722 // draw easing curve
723 if (mpEasingFuncCallback)
724 {
725 x1 = (REAL)mWaveRect.left;
726 y1 = (REAL)mWaveRect.bottom;
727 for (x = 1; x <= width; x += 1)
728 {
729 x2 = (REAL)mWaveRect.left + x;
730 y2 = (REAL)mWaveRect.bottom - height * mpEasingFuncCallback(x, width);
731 g.DrawLine(&line_pen, x1, y1, x2, y2);
732
733 x1 = x2;
734 y1 = y2;
735 }
736
737 x = mAnimationStep * width / ANIMATION_TOTAL_STEP;
738 x2 = (REAL)mWaveRect.left + x;
739 y2 = (REAL)mWaveRect.bottom - height * mpEasingFuncCallback(x, width);
740 }
741 else
742 {
743 g.DrawLine(&line_pen, mWaveRect.left, mWaveRect.bottom, mWaveRect.right, mWaveRect.top);
744 x = mAnimationStep * width / ANIMATION_TOTAL_STEP;
745 x2 = (REAL)mWaveRect.left + x;
746 y2 = (REAL)mWaveRect.bottom - (REAL)(height * x / width);
747 }
748 // draw dot in curve
749 g.FillEllipse(&red_brush, RectF(x2 - ((REAL)mAnimationDotRadius/2), y2 - ((REAL)mAnimationDotRadius/2),
750 (REAL)mAnimationDotRadius, (REAL)mAnimationDotRadius));
751
752 // draw animation rectangle
753 g.FillRectangle(&red_brush, RectF((REAL)(mWaveRect.left - (mAnimationBoxSize.cx * 3 / 2)),
754 (REAL)(y2 - (mAnimationBoxSize.cy/2)), (REAL)mAnimationBoxSize.cx, (REAL)mAnimationBoxSize.cy));
755 }
756
757 ///////////////////////////////////////////////////////////////////////////////
OnSelecteEasingFuncCombo()758 void easing_function_select_dlg::OnSelecteEasingFuncCombo()
759 {
760 int index = mEasingFuncCombo.GetCurSel();
761 mEasingFuncId = mEasingFuncCombo.GetItemData(index);
762 InvalidateRect(&mAnimationRect);
763 mAnimationStatus.SetWindowTextW(L"");
764 mAnimationStep = 0;
765 }
766
767 ///////////////////////////////////////////////////////////////////////////////
OnTestMessage(WPARAM wParam,LPARAM lParam)768 LRESULT easing_function_select_dlg::OnTestMessage(WPARAM wParam, LPARAM lParam)
769 {
770 switch (wParam)
771 {
772 case TEST_SELECT_EASING_FUNCTION:
773 mEasingFuncCombo.SelectString(0, GetTestingParam(0));
774 SendMessage(WM_COMMAND, MAKEWPARAM(IDC_EASING_FUNC_COMBO, CBN_SELCHANGE), (LPARAM)mEasingFuncCombo.m_hWnd);
775 break;
776
777 case TEST_SAVE_EASING_FUNCTION_SELECT:
778 OnOK();
779 break;
780
781 case TEST_CANCEL_EASING_FUNCTION_SELECT:
782 OnCancel();
783 break;
784 }
785
786 return 0;
787 }