GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_animation_slide_landing.c Lines: 98 98 100.0 %
Date: 2024-12-05 08:52:37 Branches: 57 58 98.3 %

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_animation.h"
30
#include "gx_utility.h"
31
#include "gx_canvas.h"
32
33
/**************************************************************************/
34
/*                                                                        */
35
/*  FUNCTION                                               RELEASE        */
36
/*                                                                        */
37
/*    _gx_animation_slide_landing                         PORTABLE C      */
38
/*                                                           6.1.11       */
39
/*  AUTHOR                                                                */
40
/*                                                                        */
41
/*    Kenneth Maxwell, Microsoft Corporation                              */
42
/*                                                                        */
43
/*  DESCRIPTION                                                           */
44
/*                                                                        */
45
/*    This function shifts the sliding screens one step to target         */
46
/*      position.                                                         */
47
/*                                                                        */
48
/*  INPUT                                                                 */
49
/*                                                                        */
50
/*    animation                             Pointer to animation control  */
51
/*                                            block                       */
52
/*                                                                        */
53
/*  OUTPUT                                                                */
54
/*                                                                        */
55
/*    status                                Completion status             */
56
/*                                                                        */
57
/*  CALLS                                                                 */
58
/*                                                                        */
59
/*    _gx_widget_detach                     Detach widget from its parent */
60
/*    _gx_widget_shift                      Change widget's position      */
61
/*    _gx_system_timer_stop                 Stop a timer for a widget     */
62
/*    _gx_animation_complete_event_send     Send a complete event to      */
63
/*                                            widget's parent             */
64
/*                                                                        */
65
/*  CALLED BY                                                             */
66
/*                                                                        */
67
/*    _gx_animation_drag_event_check                                      */
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
/*  04-25-2022     Ting Zhu                 Modified comment(s),          */
77
/*                                            added canvas and block move */
78
/*                                            support,                    */
79
/*                                            resulting in version 6.1.11 */
80
/*                                                                        */
81
/**************************************************************************/
82
1040
UINT  _gx_animation_slide_landing(GX_ANIMATION *animation)
83
{
84
1040
GX_ANIMATION_INFO *info = &animation -> gx_animation_info;
85
GX_WIDGET         *parent;
86
1040
GX_WIDGET         *target_1 = GX_NULL;
87
1040
GX_WIDGET         *target_2 = GX_NULL;
88
1040
INT                x_shift = 0;
89
1040
INT                y_shift = 0;
90
GX_RECTANGLE       target_size;
91
GX_RECTANGLE       block;
92
GX_VALUE           border_width;
93
94
1040
    parent = animation -> gx_animation_info.gx_animation_parent;
95
96
    /* Get current animation targets. */
97
1040
    if (animation -> gx_animation_slide_target_index_1 >= 0)
98
    {
99
1039
        target_1 = info -> gx_animation_slide_screen_list[animation -> gx_animation_slide_target_index_1];
100
    }
101
    else
102
    {
103
        /* Sliding animation should have 1 target at least, this should not happen. */
104
105
        /* Stop landing timer. */
106
1
        _gx_system_timer_stop(parent, GX_ANIMATION_SLIDE_TIMER);
107
108
1
        return GX_FAILURE;
109
    }
110
111
1039
    if (animation -> gx_animation_slide_target_index_2 >= 0)
112
    {
113
903
        target_2 = info -> gx_animation_slide_screen_list[animation -> gx_animation_slide_target_index_2];
114
    }
115
116
1039
    if (target_2)
117
    {
118
903
        target_size = target_2 -> gx_widget_size;
119
    }
120
    else
121
    {
122
136
        target_size = target_1 -> gx_widget_size;
123
    }
124
125
1039
    if (animation -> gx_animation_canvas)
126
    {
127
285
        _gx_utility_rectangle_shift(&target_size, animation -> gx_animation_canvas -> gx_canvas_display_offset_x,
128
285
                                    animation -> gx_animation_canvas -> gx_canvas_display_offset_y);
129
    }
130
131
1039
    if (info -> gx_animation_style & GX_ANIMATION_EASING_FUNC_MASK)
132
    {
133
40
        info -> gx_animation_steps = (GX_UBYTE)(info -> gx_animation_steps - 1);
134
135
40
        switch (animation -> gx_animation_slide_direction)
136
        {
137
20
        case GX_ANIMATION_SLIDE_LEFT:
138
        case GX_ANIMATION_SLIDE_RIGHT:
139
20
            _gx_utility_easing_function_calculate(info -> gx_animation_style,
140
20
                                                  info -> gx_animation_start_position.gx_point_x,
141
20
                                                  parent -> gx_widget_size.gx_rectangle_left,
142
20
                                                  animation -> gx_animation_total_steps - info -> gx_animation_steps,
143
20
                                                  animation -> gx_animation_total_steps, &x_shift);
144
145
20
            x_shift -= target_size.gx_rectangle_left;
146
20
            break;
147
148
20
        default:
149
20
            _gx_utility_easing_function_calculate(info -> gx_animation_style,
150
20
                                                  info -> gx_animation_start_position.gx_point_y,
151
20
                                                  parent -> gx_widget_size.gx_rectangle_top,
152
20
                                                  animation -> gx_animation_total_steps - info -> gx_animation_steps,
153
20
                                                  animation -> gx_animation_total_steps, &y_shift);
154
155
20
            y_shift -= target_size.gx_rectangle_top;
156
20
            break;
157
        }
158
    }
159
    else
160
    {
161
        /* Get landing shift value according to slide direction. */
162

999
        switch (animation -> gx_animation_slide_direction)
163
        {
164
313
        case GX_ANIMATION_SLIDE_LEFT:
165
313
            x_shift = -animation -> gx_animation_landing_speed;
166
313
            break;
167
168
249
        case GX_ANIMATION_SLIDE_RIGHT:
169
249
            x_shift = animation -> gx_animation_landing_speed;
170
249
            break;
171
172
230
        case GX_ANIMATION_SLIDE_UP:
173
230
            y_shift = -animation -> gx_animation_landing_speed;
174
230
            break;
175
176
207
        default:
177
207
            y_shift = animation -> gx_animation_landing_speed;
178
207
            break;
179
        }
180
    }
181
182

1039
    if (((info -> gx_animation_style & GX_ANIMATION_EASING_FUNC_MASK) && (info -> gx_animation_steps != 0)) ||
183

1001
        ((x_shift < 0) && ((GX_VALUE)(target_size.gx_rectangle_left + x_shift) > parent -> gx_widget_size.gx_rectangle_left)) ||
184

719
        ((x_shift > 0) && ((GX_VALUE)(target_size.gx_rectangle_left + x_shift) < parent -> gx_widget_size.gx_rectangle_left)) ||
185

494
        ((y_shift < 0) && ((GX_VALUE)(target_size.gx_rectangle_top + y_shift) > parent -> gx_widget_size.gx_rectangle_top)) ||
186

288
        ((y_shift > 0) && ((GX_VALUE)(target_size.gx_rectangle_top + y_shift) < parent -> gx_widget_size.gx_rectangle_top)))
187
    {
188
937
        if (animation -> gx_animation_canvas)
189
        {
190
255
            _gx_canvas_offset_set(animation -> gx_animation_canvas,
191
255
                                  (GX_VALUE)(animation -> gx_animation_canvas -> gx_canvas_display_offset_x + x_shift),
192
255
                                  (GX_VALUE)(animation -> gx_animation_canvas -> gx_canvas_display_offset_y + y_shift));
193
        }
194
        else
195
        {
196
            /* Shift animation targets one step toward target position.  */
197
198
682
            if (info -> gx_animation_style & GX_ANIMATION_BLOCK_MOVE)
199
            {
200
255
                _gx_widget_scroll_shift(target_1, (GX_VALUE)x_shift, (GX_VALUE)y_shift, GX_TRUE);
201
202
255
                if (target_2)
203
                {
204
231
                    _gx_widget_scroll_shift(target_2, (GX_VALUE)x_shift, (GX_VALUE)y_shift, GX_TRUE);
205
                }
206
            }
207
            else
208
            {
209
427
                _gx_widget_shift(target_1, (GX_VALUE)x_shift, (GX_VALUE)y_shift, GX_TRUE);
210
211
427
                if (target_2)
212
                {
213
370
                    _gx_widget_shift(target_2, (GX_VALUE)x_shift, (GX_VALUE)y_shift, GX_TRUE);
214
                }
215
            }
216
        }
217
    }
218
    else
219
    {
220
        /* Shift animation targets to the target position. */
221
222
        /* Stop landing timer. */
223
102
        _gx_system_timer_stop(parent, GX_ANIMATION_SLIDE_TIMER);
224
225
        /* Calculate the distance from current postion to final position. */
226
102
        if (info -> gx_animation_style & GX_ANIMATION_VERTICAL)
227
        {
228
46
            y_shift = parent -> gx_widget_size.gx_rectangle_top - target_size.gx_rectangle_top;
229
        }
230
        else
231
        {
232
56
            x_shift = parent -> gx_widget_size.gx_rectangle_left - target_size.gx_rectangle_left;
233
        }
234
235
102
        if (animation -> gx_animation_canvas)
236
        {
237
            /* hide the animation root */
238
30
            if (target_1 -> gx_widget_parent)
239
            {
240
30
                _gx_widget_hide(target_1 -> gx_widget_parent);
241
            }
242
243
            /* attach the widget to it's parent */
244
30
            if (target_2)
245
            {
246
20
                _gx_widget_detach(target_1);
247
20
                target_1 = target_2;
248
            }
249
250
30
            _gx_widget_shift(target_1,
251
30
                             (GX_VALUE)(x_shift + animation -> gx_animation_canvas -> gx_canvas_display_offset_x),
252
30
                             (GX_VALUE)(y_shift + animation -> gx_animation_canvas -> gx_canvas_display_offset_y), GX_TRUE);
253
254
30
            _gx_widget_attach(parent, target_1);
255
256
30
            _gx_canvas_hide(animation -> gx_animation_canvas);
257
30
            _gx_system_canvas_refresh();
258
        }
259
        else
260
        {
261
72
            if (target_2)
262
            {
263
                /* Detach the first target. */
264
51
                _gx_widget_detach(target_1);
265
266
51
                target_1 = target_2;
267
            }
268
269
            /* No second target, just move the first target to its final position. */
270
72
            if (info -> gx_animation_style & GX_ANIMATION_BLOCK_MOVE)
271
            {
272
30
                _gx_widget_scroll_shift(target_1, (GX_VALUE)x_shift, (GX_VALUE)y_shift, GX_TRUE);
273
            }
274
            else
275
            {
276
42
                _gx_widget_shift(target_1, (GX_VALUE)x_shift, (GX_VALUE)y_shift, GX_TRUE);
277
            }
278
        }
279
280
        /* Reset animation information. */
281
102
        animation -> gx_animation_slide_target_index_1 = -1;
282
102
        animation -> gx_animation_slide_target_index_2 = -1;
283
102
        animation -> gx_animation_status = GX_ANIMATION_IDLE;
284
285
        /* Send animation complete event.  */
286
102
        _gx_animation_complete_event_send(animation);
287
    }
288
289
1039
    if (info -> gx_animation_style & GX_ANIMATION_BLOCK_MOVE)
290
    {
291
285
        _gx_widget_border_width_get(parent, &border_width);
292
285
        _gx_widget_client_get(parent, border_width, &block);
293
285
        _gx_widget_block_move(parent, &block, (GX_VALUE)x_shift, (GX_VALUE)y_shift);
294
    }
295
296
    /* Return completion status code. */
297
1039
    return(GX_SUCCESS);
298
}
299