GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_animation_slide_landing.c Lines: 98 98 100.0 %
Date: 2026-03-06 19:21:09 Branches: 57 58 98.3 %

Line Branch Exec Source
1
/***************************************************************************
2
 * Copyright (c) 2024 Microsoft Corporation
3
 * Copyright (c) 2026-present Eclipse ThreadX contributors
4
 *
5
 * This program and the accompanying materials are made available under the
6
 * terms of the MIT License which is available at
7
 * https://opensource.org/licenses/MIT.
8
 *
9
 * SPDX-License-Identifier: MIT
10
 **************************************************************************/
11
12
13
/**************************************************************************/
14
/**************************************************************************/
15
/**                                                                       */
16
/** GUIX Component                                                        */
17
/**                                                                       */
18
/**   Animation Management (Animation)                                    */
19
/**                                                                       */
20
/**************************************************************************/
21
22
#define GX_SOURCE_CODE
23
24
25
/* Include necessary system files.  */
26
27
#include "gx_api.h"
28
#include "gx_widget.h"
29
#include "gx_system.h"
30
#include "gx_animation.h"
31
#include "gx_utility.h"
32
#include "gx_canvas.h"
33
34
/**************************************************************************/
35
/*                                                                        */
36
/*  FUNCTION                                               RELEASE        */
37
/*                                                                        */
38
/*    _gx_animation_slide_landing                         PORTABLE C      */
39
/*                                                           6.1.11       */
40
/*  AUTHOR                                                                */
41
/*                                                                        */
42
/*    Kenneth Maxwell, Microsoft Corporation                              */
43
/*                                                                        */
44
/*  DESCRIPTION                                                           */
45
/*                                                                        */
46
/*    This function shifts the sliding screens one step to target         */
47
/*      position.                                                         */
48
/*                                                                        */
49
/*  INPUT                                                                 */
50
/*                                                                        */
51
/*    animation                             Pointer to animation control  */
52
/*                                            block                       */
53
/*                                                                        */
54
/*  OUTPUT                                                                */
55
/*                                                                        */
56
/*    status                                Completion status             */
57
/*                                                                        */
58
/*  CALLS                                                                 */
59
/*                                                                        */
60
/*    _gx_widget_detach                     Detach widget from its parent */
61
/*    _gx_widget_shift                      Change widget's position      */
62
/*    _gx_system_timer_stop                 Stop a timer for a widget     */
63
/*    _gx_animation_complete_event_send     Send a complete event to      */
64
/*                                            widget's parent             */
65
/*                                                                        */
66
/*  CALLED BY                                                             */
67
/*                                                                        */
68
/*    _gx_animation_drag_event_check                                      */
69
/*                                                                        */
70
/**************************************************************************/
71
#if (GX_ANIMATION_POOL_SIZE > 0)
72
1040
UINT  _gx_animation_slide_landing(GX_ANIMATION *animation)
73
{
74
1040
GX_ANIMATION_INFO *info = &animation -> gx_animation_info;
75
GX_WIDGET         *parent;
76
1040
GX_WIDGET         *target_1 = GX_NULL;
77
1040
GX_WIDGET         *target_2 = GX_NULL;
78
1040
INT                x_shift = 0;
79
1040
INT                y_shift = 0;
80
GX_RECTANGLE       target_size;
81
GX_RECTANGLE       block;
82
GX_VALUE           border_width;
83
84
1040
    parent = animation -> gx_animation_info.gx_animation_parent;
85
86
    /* Get current animation targets. */
87
1040
    if (animation -> gx_animation_slide_target_index_1 >= 0)
88
    {
89
1039
        target_1 = info -> gx_animation_slide_screen_list[animation -> gx_animation_slide_target_index_1];
90
    }
91
    else
92
    {
93
        /* Sliding animation should have 1 target at least, this should not happen. */
94
95
        /* Stop landing timer. */
96
1
        _gx_system_timer_stop(parent, GX_ANIMATION_SLIDE_TIMER);
97
98
1
        return GX_FAILURE;
99
    }
100
101
1039
    if (animation -> gx_animation_slide_target_index_2 >= 0)
102
    {
103
903
        target_2 = info -> gx_animation_slide_screen_list[animation -> gx_animation_slide_target_index_2];
104
    }
105
106
1039
    if (target_2)
107
    {
108
903
        target_size = target_2 -> gx_widget_size;
109
    }
110
    else
111
    {
112
136
        target_size = target_1 -> gx_widget_size;
113
    }
114
115
1039
    if (animation -> gx_animation_canvas)
116
    {
117
285
        _gx_utility_rectangle_shift(&target_size, animation -> gx_animation_canvas -> gx_canvas_display_offset_x,
118
285
                                    animation -> gx_animation_canvas -> gx_canvas_display_offset_y);
119
    }
120
121
1039
    if (info -> gx_animation_style & GX_ANIMATION_EASING_FUNC_MASK)
122
    {
123
40
        info -> gx_animation_steps = (GX_UBYTE)(info -> gx_animation_steps - 1);
124
125
40
        switch (animation -> gx_animation_slide_direction)
126
        {
127
20
        case GX_ANIMATION_SLIDE_LEFT:
128
        case GX_ANIMATION_SLIDE_RIGHT:
129
20
            _gx_utility_easing_function_calculate(info -> gx_animation_style,
130
20
                                                  info -> gx_animation_start_position.gx_point_x,
131
20
                                                  parent -> gx_widget_size.gx_rectangle_left,
132
20
                                                  animation -> gx_animation_total_steps - info -> gx_animation_steps,
133
20
                                                  animation -> gx_animation_total_steps, &x_shift);
134
135
20
            x_shift -= target_size.gx_rectangle_left;
136
20
            break;
137
138
20
        default:
139
20
            _gx_utility_easing_function_calculate(info -> gx_animation_style,
140
20
                                                  info -> gx_animation_start_position.gx_point_y,
141
20
                                                  parent -> gx_widget_size.gx_rectangle_top,
142
20
                                                  animation -> gx_animation_total_steps - info -> gx_animation_steps,
143
20
                                                  animation -> gx_animation_total_steps, &y_shift);
144
145
20
            y_shift -= target_size.gx_rectangle_top;
146
20
            break;
147
        }
148
    }
149
    else
150
    {
151
        /* Get landing shift value according to slide direction. */
152

999
        switch (animation -> gx_animation_slide_direction)
153
        {
154
313
        case GX_ANIMATION_SLIDE_LEFT:
155
313
            x_shift = -animation -> gx_animation_landing_speed;
156
313
            break;
157
158
249
        case GX_ANIMATION_SLIDE_RIGHT:
159
249
            x_shift = animation -> gx_animation_landing_speed;
160
249
            break;
161
162
230
        case GX_ANIMATION_SLIDE_UP:
163
230
            y_shift = -animation -> gx_animation_landing_speed;
164
230
            break;
165
166
207
        default:
167
207
            y_shift = animation -> gx_animation_landing_speed;
168
207
            break;
169
        }
170
    }
171
172

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

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

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

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

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