GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_animation_update.c Lines: 66 71 93.0 %
Date: 2024-12-05 08:52:37 Branches: 27 30 90.0 %

Line Branch Exec Source
1
/***************************************************************************
2
 * Copyright (c) 2024 Microsoft Corporation
3
 *
4
 * This program and the accompanying materials are made available under the
5
 * terms of the MIT License which is available at
6
 * https://opensource.org/licenses/MIT.
7
 *
8
 * SPDX-License-Identifier: MIT
9
 **************************************************************************/
10
11
12
/**************************************************************************/
13
/**************************************************************************/
14
/**                                                                       */
15
/** GUIX Component                                                        */
16
/**                                                                       */
17
/**   Animation Management (Animation)                                    */
18
/**                                                                       */
19
/**************************************************************************/
20
21
#define GX_SOURCE_CODE
22
23
24
/* Include necessary system files.  */
25
26
#include "gx_api.h"
27
#include "gx_widget.h"
28
#include "gx_system.h"
29
#include "gx_canvas.h"
30
#include "gx_utility.h"
31
#include "gx_animation.h"
32
33
/**************************************************************************/
34
/*                                                                        */
35
/*  FUNCTION                                               RELEASE        */
36
/*                                                                        */
37
/*    _gx_animation_update                                PORTABLE C      */
38
/*                                                           6.1.11       */
39
/*  AUTHOR                                                                */
40
/*                                                                        */
41
/*    Kenneth Maxwell, Microsoft Corporation                              */
42
/*                                                                        */
43
/*  DESCRIPTION                                                           */
44
/*                                                                        */
45
/*    This function executes one step on an animation sequence.           */
46
/*                                                                        */
47
/*                                                                        */
48
/*  INPUT                                                                 */
49
/*                                                                        */
50
/*    None                                                                */
51
/*                                                                        */
52
/*  OUTPUT                                                                */
53
/*                                                                        */
54
/*    None                                                                */
55
/*                                                                        */
56
/*  CALLS                                                                 */
57
/*                                                                        */
58
/*    _gx_canvas_alpha_set                  Set the alpha of canvas       */
59
/*    _gx_animation_complete                Called when an animation      */
60
/*                                            sequence is finished        */
61
/*    _gx_canvas_offset_set                 Set the offset of canvas      */
62
/*    _gx_widget_shift                      Shift a widget                */
63
/*    _gx_animation_stop                    Stop an animation             */
64
/*                                                                        */
65
/*  CALLED BY                                                             */
66
/*                                                                        */
67
/*    _gx_system_timer_update               Update active system timers   */
68
/*                                                                        */
69
/*  RELEASE HISTORY                                                       */
70
/*                                                                        */
71
/*    DATE              NAME                      DESCRIPTION             */
72
/*                                                                        */
73
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
74
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
75
/*                                            resulting in version 6.1    */
76
/*  12-31-2020     Kenneth Maxwell          Modified comment(s), improve  */
77
/*                                            linear animation accuracy,  */
78
/*                                            resulting in version 6.1.3  */
79
/*  04-25-2022     Ting Zhu                 Modified comment(s),          */
80
/*                                            added block move support,   */
81
/*                                            resulting in version 6.1.11 */
82
/*                                                                        */
83
/**************************************************************************/
84
4782
VOID _gx_animation_update(VOID)
85
{
86
GX_ANIMATION      *animation;
87
GX_ANIMATION      *next;
88
GX_WIDGET         *target;
89
INT                test_alpha;
90
INT                x_current;
91
INT                y_current;
92
4782
INT                x_trans = 0;
93
4782
INT                y_trans = 0;
94
GX_ANIMATION_INFO *info;
95
GX_WIDGET         *parent;
96
GX_RECTANGLE       block;
97
98
4782
    animation = _gx_system_animation_list;
99
100
11450
    while (animation)
101
    {
102
6668
        info = &animation -> gx_animation_info;
103
6668
        next = animation -> gx_animation_next;
104
105
        /* has this animation timer expired ? */
106
6668
        if (animation -> gx_animation_timer > 1)
107
        {
108
            /* no, just decrement timer count and continue */
109
1497
            animation -> gx_animation_timer--;
110
1497
            animation = next;
111
1497
            continue;
112
        }
113
114
5171
        if (info -> gx_animation_style & GX_ANIMATION_SCREEN_DRAG)
115
        {
116
3552
            animation = next;
117
3552
            continue;
118
        }
119
120
        /* the animation timer has expired. First reload the
121
           timer counter in case we are not on last step
122
         */
123
124
1619
        info -> gx_animation_steps = (GX_UBYTE)(info -> gx_animation_steps - 1);
125
126
1619
        if (info -> gx_animation_steps <= 0)
127
        {
128
57
            _gx_animation_complete(animation);
129
57
            animation = next;
130
57
            continue;
131
        }
132
        else
133
        {
134
1562
            animation -> gx_animation_timer = info -> gx_animation_frame_interval;
135
        }
136
137
1562
        target = info -> gx_animation_target;
138
139
        /* check for a fade style animation */
140
1562
        if (info -> gx_animation_end_alpha !=
141
1562
            info -> gx_animation_start_alpha)
142
        {
143
251
            _gx_utility_easing_function_calculate(info -> gx_animation_style,
144
251
                                                  info -> gx_animation_start_alpha,
145
251
                                                  info -> gx_animation_end_alpha,
146
251
                                                  animation -> gx_animation_total_steps - info -> gx_animation_steps,
147
251
                                                  animation -> gx_animation_total_steps, &test_alpha);
148
149
251
            if (animation -> gx_animation_canvas)
150
            {
151
18
                _gx_canvas_alpha_set(animation -> gx_animation_canvas, (GX_UBYTE)test_alpha);
152
            }
153
#if defined(GX_BRUSH_ALPHA_SUPPORT)
154
            else
155
            {
156
233
                target -> gx_widget_alpha = (GX_UBYTE)test_alpha;
157
233
                if (test_alpha == 0xff)
158
                {
159
2
                    _gx_system_dirty_mark(target);
160
                }
161
                else
162
                {
163
231
                    _gx_system_dirty_partial_add(target -> gx_widget_parent, &target -> gx_widget_size);
164
                }
165
            }
166
#endif
167
        }
168
169
        /* check for a slide style animation */
170
1562
        if ((info -> gx_animation_end_position.gx_point_x !=
171
1562
             info -> gx_animation_start_position.gx_point_x) ||
172
1389
            (info -> gx_animation_end_position.gx_point_y !=
173
1389
             info -> gx_animation_start_position.gx_point_y))
174
        {
175
1439
            if (animation -> gx_animation_canvas)
176
            {
177
46
                x_current = animation -> gx_animation_canvas -> gx_canvas_display_offset_x;
178
46
                y_current = animation -> gx_animation_canvas -> gx_canvas_display_offset_y;
179
            }
180
            else
181
            {
182
1393
                x_current = target -> gx_widget_size.gx_rectangle_left;
183
1393
                y_current = target -> gx_widget_size.gx_rectangle_top;
184
            }
185
186
1439
            if (info -> gx_animation_start_position.gx_point_x != info -> gx_animation_end_position.gx_point_x)
187
            {
188
173
                _gx_utility_easing_function_calculate(info -> gx_animation_style,
189
173
                                                      info -> gx_animation_start_position.gx_point_x,
190
173
                                                      info -> gx_animation_end_position.gx_point_x,
191
173
                                                      animation -> gx_animation_total_steps - info -> gx_animation_steps,
192
173
                                                      animation -> gx_animation_total_steps, &x_trans);
193
194
173
                x_trans -= x_current;
195
            }
196
            else
197
            {
198
1266
                x_trans = 0;
199
            }
200
201
1439
            if (info -> gx_animation_start_position.gx_point_y != info -> gx_animation_end_position.gx_point_y)
202
            {
203
1289
                _gx_utility_easing_function_calculate(info -> gx_animation_style,
204
1289
                                                      info -> gx_animation_start_position.gx_point_y,
205
1289
                                                      info -> gx_animation_end_position.gx_point_y,
206
1289
                                                      animation -> gx_animation_total_steps - info -> gx_animation_steps,
207
1289
                                                      animation -> gx_animation_total_steps, &y_trans);
208
209
1289
                y_trans -= y_current;
210
            }
211
            else
212
            {
213
150
                y_trans = 0;
214
            }
215
216
            /* still moving */
217
1439
            if (animation -> gx_animation_canvas)
218
            {
219
                /* adjust canvas offset */
220
46
                _gx_canvas_offset_set(animation -> gx_animation_canvas,
221
46
                                      (GX_VALUE)(x_current + x_trans), (GX_VALUE)(y_current + y_trans));
222
            }
223
            else
224
            {
225
                /* adjust target position */
226
1393
                if (animation -> gx_animation_info.gx_animation_style & GX_ANIMATION_BLOCK_MOVE)
227
                {
228
                    parent = animation -> gx_animation_info.gx_animation_parent;
229
                    if (_gx_utility_rectangle_overlap_detect(&target -> gx_widget_size, &parent -> gx_widget_size, &block))
230
                    {
231
                        _gx_widget_scroll_shift(target, (GX_VALUE)x_trans, (GX_VALUE)y_trans, GX_TRUE);
232
                        _gx_widget_block_move(parent, &block, (GX_VALUE)x_trans, (GX_VALUE)y_trans);
233
                    }
234
                    else
235
                    {
236
                        _gx_widget_shift(target, (GX_VALUE)x_trans, (GX_VALUE)y_trans, GX_TRUE);
237
                    }
238
                }
239
                else
240
                {
241
1393
                    _gx_widget_shift(target, (GX_VALUE)x_trans, (GX_VALUE)y_trans, GX_TRUE);
242
                }
243
            }
244
        }
245
1562
        animation = next;
246
    }
247
4782
}
248