GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_animation_drag_tracking_start.c Lines: 92 95 96.8 %
Date: 2026-03-06 19:21:09 Branches: 53 62 85.5 %

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_animation.h"
30
#include "gx_system.h"
31
#include "gx_canvas.h"
32
33
/**************************************************************************/
34
/*                                                                        */
35
/*  FUNCTION                                               RELEASE        */
36
/*                                                                        */
37
/*    _gx_animation_drag_tracking_start                   PORTABLE C      */
38
/*                                                           6.1.11       */
39
/*  AUTHOR                                                                */
40
/*                                                                        */
41
/*    Kenneth Maxwell, Microsoft Corporation                              */
42
/*                                                                        */
43
/*  DESCRIPTION                                                           */
44
/*                                                                        */
45
/*    This function prepares for screen slide animation.                  */
46
/*                                                                        */
47
/*  INPUT                                                                 */
48
/*                                                                        */
49
/*    animation                             Pointer to animation control  */
50
/*                                            block                       */
51
/*                                                                        */
52
/*  OUTPUT                                                                */
53
/*                                                                        */
54
/*    status                                Completion status             */
55
/*                                                                        */
56
/*  CALLS                                                                 */
57
/*                                                                        */
58
/*    _gx_widget_resize                     Resize widget                 */
59
/*    _gx_widget_attach                     Attach a widget to its parent */
60
/*                                                                        */
61
/*  CALLED BY                                                             */
62
/*                                                                        */
63
/*    _gx_animation_drag_event_check                                      */
64
/*                                                                        */
65
/**************************************************************************/
66
#if (GX_ANIMATION_POOL_SIZE > 0)
67
117
UINT  _gx_animation_drag_tracking_start(GX_ANIMATION *animation, GX_POINT penpos)
68
{
69
GX_ANIMATION_INFO *info;
70
GX_RECTANGLE       size;
71
INT                width;
72
GX_WIDGET         *target_1;
73
117
GX_WIDGET         *target_2 = GX_NULL;
74
INT                index;
75
INT                current_pos;
76
GX_WINDOW_ROOT    *root;
77
GX_VALUE           left;
78
GX_VALUE           top;
79
VOID               (*active_display_area_set)(INT layer, GX_RECTANGLE *size);
80
81
117
    info = &animation -> gx_animation_info;
82
83
117
    target_1 = info -> gx_animation_slide_screen_list[0];
84
117
    index = 0;
85
86
    /* Search for visible screen, which is the first animation target. */
87
465
    while (target_1)
88
    {
89
348
        if (target_1 -> gx_widget_status & GX_STATUS_VISIBLE)
90
        {
91
116
            animation -> gx_animation_slide_target_index_1 = (GX_VALUE)index;
92
        }
93
348
        index++;
94
348
        target_1 = info -> gx_animation_slide_screen_list[index];
95
    }
96
97
117
    animation -> gx_animation_slide_screen_list_size = (USHORT)index;
98
99
117
    if (animation -> gx_animation_slide_target_index_1 == -1)
100
    {
101
1
        return(GX_FAILURE);
102
    }
103
104
116
    if (info -> gx_animation_style & GX_ANIMATION_VERTICAL)
105
    {
106
53
        current_pos = penpos.gx_point_y;
107
    }
108
    else
109
    {
110
63
        current_pos = penpos.gx_point_x;
111
    }
112
113
    /* Find second animation target according to sliding direction. */
114
116
    if (current_pos < animation -> gx_animation_slide_tracking_start_pos)
115
    {
116
        /* Sliding left/up. */
117
66
        index = animation -> gx_animation_slide_target_index_1 + 1;
118
119
66
        if ((index >= animation -> gx_animation_slide_screen_list_size) &&
120
31
            (info -> gx_animation_style & GX_ANIMATION_WRAP))
121
        {
122
6
            index = 0;
123
        }
124
    }
125
    else
126
    {
127
        /* Sliding right/down. */
128
50
        index = animation -> gx_animation_slide_target_index_1 - 1;
129
130

50
        if ((index < 0) && (info -> gx_animation_style & GX_ANIMATION_WRAP))
131
        {
132
15
            index = animation -> gx_animation_slide_screen_list_size - 1;
133
        }
134
    }
135
136
116
    if (info -> gx_animation_style & GX_ANIMATION_VERTICAL)
137
    {
138
53
        if (current_pos < animation -> gx_animation_slide_tracking_start_pos)
139
        {
140
32
            animation -> gx_animation_slide_direction = GX_ANIMATION_SLIDE_UP;
141
        }
142
        else
143
        {
144
21
            animation -> gx_animation_slide_direction = GX_ANIMATION_SLIDE_DOWN;
145
        }
146
    }
147
    else
148
    {
149
63
        if (current_pos < animation -> gx_animation_slide_tracking_start_pos)
150
        {
151
34
            animation -> gx_animation_slide_direction = GX_ANIMATION_SLIDE_LEFT;
152
        }
153
        else
154
        {
155
29
            animation -> gx_animation_slide_direction = GX_ANIMATION_SLIDE_RIGHT;
156
        }
157
    }
158
159
116
    target_1 = info -> gx_animation_slide_screen_list[animation -> gx_animation_slide_target_index_1];
160
161

116
    if ((index >= 0) && (index < animation -> gx_animation_slide_screen_list_size))
162
    {
163
84
        animation -> gx_animation_slide_target_index_2 = (GX_VALUE)(index);
164
165
84
        target_2 = info -> gx_animation_slide_screen_list[index];
166
167
84
        size = target_2 -> gx_widget_size;
168
169
84
        if (info -> gx_animation_style & GX_ANIMATION_VERTICAL)
170
        {
171
38
            width = size.gx_rectangle_bottom - size.gx_rectangle_top + 1;
172
173
38
            switch (animation -> gx_animation_slide_direction)
174
            {
175
20
            case GX_ANIMATION_SLIDE_UP:
176
177
                /* Slide up. */
178
20
                size.gx_rectangle_top = (GX_VALUE)(target_1 -> gx_widget_size.gx_rectangle_bottom + 1);
179
20
                size.gx_rectangle_bottom = (GX_VALUE)(size.gx_rectangle_top + width - 1);
180
20
                break;
181
182
18
            default:
183
                /* Slide down. */
184
18
                size.gx_rectangle_bottom = (GX_VALUE)(target_1 -> gx_widget_size.gx_rectangle_top - 1);
185
18
                size.gx_rectangle_top = (GX_VALUE)(size.gx_rectangle_bottom - width + 1);
186
18
                break;
187
            }
188
38
            size.gx_rectangle_left = (GX_VALUE)target_1 -> gx_widget_size.gx_rectangle_left;
189
38
            size.gx_rectangle_right = (GX_VALUE)target_1 -> gx_widget_size.gx_rectangle_right;
190
        }
191
        else
192
        {
193
46
            width = size.gx_rectangle_right - size.gx_rectangle_left + 1;
194
195
46
            switch (animation -> gx_animation_slide_direction)
196
            {
197
21
            case GX_ANIMATION_SLIDE_LEFT:
198
                /* Slide left. */
199
21
                size.gx_rectangle_left = (GX_VALUE)(target_1 -> gx_widget_size.gx_rectangle_right + 1);
200
21
                size.gx_rectangle_right = (GX_VALUE)(size.gx_rectangle_left + width - 1);
201
21
                break;
202
25
            default:
203
                /* Slide right. */
204
25
                size.gx_rectangle_right = (GX_VALUE)(target_1 -> gx_widget_size.gx_rectangle_left - 1);
205
25
                size.gx_rectangle_left = (GX_VALUE)(size.gx_rectangle_right - width + 1);
206
25
                break;
207
            }
208
209
46
            size.gx_rectangle_top = (GX_VALUE)target_1 -> gx_widget_size.gx_rectangle_top;
210
46
            size.gx_rectangle_bottom = (GX_VALUE)target_1 -> gx_widget_size.gx_rectangle_bottom;
211
        }
212
213
        /* Resize the second animation target. */
214
84
        _gx_widget_resize(target_2, &size);
215
216
84
        if (!animation -> gx_animation_canvas)
217
        {
218
219
            /* Attach the second target to animation parent.  */
220
60
            _gx_widget_attach(info -> gx_animation_parent, target_2);
221
        }
222
    }
223
    else
224
    {
225
32
        animation -> gx_animation_slide_target_index_2 = -1;
226
    }
227
228
116
    if (animation -> gx_animation_canvas)
229
    {
230
        /* Find animation root.  */
231
34
        root = _gx_system_root_window_created_list;
232

52
        while (root && root -> gx_window_root_canvas != animation -> gx_animation_canvas)
233
        {
234
18
            root = (GX_WINDOW_ROOT *)root -> gx_widget_next;
235
        }
236
237
34
        if (animation -> gx_animation_slide_direction == GX_ANIMATION_SLIDE_UP ||
238

24
            animation -> gx_animation_slide_direction == GX_ANIMATION_SLIDE_LEFT ||
239
            (!target_2))
240
        {
241
20
            left = target_1 -> gx_widget_size.gx_rectangle_left;
242
20
            top = target_1 -> gx_widget_size.gx_rectangle_top;
243
        }
244
        else
245
        {
246
14
            left = target_2 -> gx_widget_size.gx_rectangle_left;
247
14
            top = target_2 -> gx_widget_size.gx_rectangle_top;
248
        }
249
250

34
        if (left || top)
251
        {
252
34
            _gx_widget_shift(target_1, (GX_VALUE)-left, (GX_VALUE)-top, GX_TRUE);
253
254
34
            if (target_2)
255
            {
256
24
                _gx_widget_shift(target_2, (GX_VALUE)-left, (GX_VALUE)-top, GX_TRUE);
257
            }
258
        }
259
260
        /* Position the canvas at the animation starting position.  */
261
34
        _gx_canvas_offset_set(animation -> gx_animation_canvas, left, top);
262
263
34
        if (animation -> gx_animation_canvas -> gx_canvas_hardware_layer >= 0)
264
        {
265
            active_display_area_set = animation -> gx_animation_canvas -> gx_canvas_display -> gx_display_layer_services -> gx_display_layer_active_display_area_set;
266
267
            if (active_display_area_set)
268
            {
269
                /* Set active display area as the animation parent widget size. */
270
                active_display_area_set(animation -> gx_animation_canvas -> gx_canvas_hardware_layer, &info -> gx_animation_parent -> gx_widget_size);
271
            }
272
        }
273
274
34
        if (root)
275
        {
276
            /* Link the target to the animation root window.  */
277
34
            _gx_widget_attach((GX_WIDGET *)root, target_1);
278
279
34
            if (target_2)
280
            {
281
24
                _gx_widget_attach((GX_WIDGET *)root, target_2);
282
            }
283
284
            /* and show the animation root window to make everything visible */
285
34
            _gx_widget_show((GX_WIDGET *)root);
286
34
            _gx_canvas_drawing_initiate(animation -> gx_animation_canvas, (GX_WIDGET *)root, &root -> gx_widget_size);
287
34
            _gx_widget_children_draw((GX_WIDGET *)root);
288
34
            _gx_canvas_drawing_complete(animation -> gx_animation_canvas, GX_FALSE);
289
290
            /* set the initial alpha and make our canvas visible */
291
34
            _gx_canvas_alpha_set(animation -> gx_animation_canvas, info -> gx_animation_start_alpha);
292
34
            _gx_canvas_show(animation -> gx_animation_canvas);
293
        }
294
    }
295
296
    /* Return completion status code. */
297
116
    return(GX_SUCCESS);
298
}
299
#endif