GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_animation_drag_tracking_start.c Lines: 93 96 96.9 %
Date: 2026-08-28 02:37:13 Branches: 56 66 84.8 %

Line Branch Exec Source
1
/***************************************************************************
2
 * Copyright (c) 2024 Microsoft Corporation
3
 * Copyright (c) 2026 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
// Some portions generated by Copilot (Claude Sonnet 4.6).
12
// Some portions generated by Claude Code (Opus 5).
13
14
15
/**************************************************************************/
16
/**************************************************************************/
17
/**                                                                       */
18
/** GUIX Component                                                        */
19
/**                                                                       */
20
/**   Animation Management (Animation)                                    */
21
/**                                                                       */
22
/**************************************************************************/
23
24
#define GX_SOURCE_CODE
25
26
27
/* Include necessary system files.  */
28
29
#include "gx_api.h"
30
#include "gx_widget.h"
31
#include "gx_animation.h"
32
#include "gx_system.h"
33
#include "gx_canvas.h"
34
35
/**************************************************************************/
36
/*                                                                        */
37
/*  FUNCTION                                               RELEASE        */
38
/*                                                                        */
39
/*    _gx_animation_drag_tracking_start                   PORTABLE C      */
40
/*                                                           6.1.11       */
41
/*  AUTHOR                                                                */
42
/*                                                                        */
43
/*    Kenneth Maxwell, Microsoft Corporation                              */
44
/*                                                                        */
45
/*  DESCRIPTION                                                           */
46
/*                                                                        */
47
/*    This function prepares for screen slide animation.                  */
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_resize                     Resize widget                 */
61
/*    _gx_widget_attach                     Attach a widget to its parent */
62
/*                                                                        */
63
/*  CALLED BY                                                             */
64
/*                                                                        */
65
/*    _gx_animation_drag_event_check                                      */
66
/*                                                                        */
67
/**************************************************************************/
68
#if (GX_ANIMATION_POOL_SIZE > 0)
69
117
UINT  _gx_animation_drag_tracking_start(GX_ANIMATION *animation, GX_POINT penpos)
70
{
71
GX_ANIMATION_INFO *info;
72
GX_RECTANGLE       size;
73
INT                width;
74
GX_WIDGET         *target_1;
75
117
GX_WIDGET         *target_2 = GX_NULL;
76
INT                index;
77
INT                current_pos;
78
GX_WINDOW_ROOT    *root;
79
GX_VALUE           left;
80
GX_VALUE           top;
81
UINT               draw_status;
82
VOID               (*active_display_area_set)(INT layer, GX_RECTANGLE *size);
83
84
117
    info = &animation -> gx_animation_info;
85
86
117
    target_1 = info -> gx_animation_slide_screen_list[0];
87
117
    index = 0;
88
89
    /* Search for visible screen, which is the first animation target. */
90
465
    while (target_1)
91
    {
92
348
        if (target_1 -> gx_widget_status & GX_STATUS_VISIBLE)
93
        {
94
116
            animation -> gx_animation_slide_target_index_1 = (GX_VALUE)index;
95
        }
96
348
        index++;
97
348
        target_1 = info -> gx_animation_slide_screen_list[index];
98
    }
99
100
117
    animation -> gx_animation_slide_screen_list_size = (USHORT)index;
101
102
117
    if (animation -> gx_animation_slide_target_index_1 == -1)
103
    {
104
1
        return(GX_FAILURE);
105
    }
106
107
116
    if (info -> gx_animation_style & GX_ANIMATION_VERTICAL)
108
    {
109
53
        current_pos = penpos.gx_point_y;
110
    }
111
    else
112
    {
113
63
        current_pos = penpos.gx_point_x;
114
    }
115
116
    /* Find second animation target according to sliding direction. */
117
116
    if (current_pos < animation -> gx_animation_slide_tracking_start_pos)
118
    {
119
        /* Sliding left/up. */
120
66
        index = animation -> gx_animation_slide_target_index_1 + 1;
121
122
66
        if ((index >= animation -> gx_animation_slide_screen_list_size) &&
123
31
            (info -> gx_animation_style & GX_ANIMATION_WRAP))
124
        {
125
6
            index = 0;
126
        }
127
    }
128
    else
129
    {
130
        /* Sliding right/down. */
131
50
        index = animation -> gx_animation_slide_target_index_1 - 1;
132
133

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

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

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

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

34
        if (left || top)
254
        {
255
34
            _gx_widget_shift(target_1, (GX_VALUE)-left, (GX_VALUE)-top, GX_TRUE);
256
257
34
            if (target_2)
258
            {
259
24
                _gx_widget_shift(target_2, (GX_VALUE)-left, (GX_VALUE)-top, GX_TRUE);
260
            }
261
        }
262
263
        /* Position the canvas at the animation starting position.  */
264
34
        _gx_canvas_offset_set(animation -> gx_animation_canvas, left, top);
265
266
34
        if (animation -> gx_animation_canvas -> gx_canvas_hardware_layer >= 0)
267
        {
268
            active_display_area_set = animation -> gx_animation_canvas -> gx_canvas_display -> gx_display_layer_services -> gx_display_layer_active_display_area_set;
269
270
            if (active_display_area_set)
271
            {
272
                /* Set active display area as the animation parent widget size. */
273
                active_display_area_set(animation -> gx_animation_canvas -> gx_canvas_hardware_layer, &info -> gx_animation_parent -> gx_widget_size);
274
            }
275
        }
276
277
34
        if (root)
278
        {
279
            /* Link the target to the animation root window.  */
280
34
            _gx_widget_attach((GX_WIDGET *)root, target_1);
281
282
34
            if (target_2)
283
            {
284
24
                _gx_widget_attach((GX_WIDGET *)root, target_2);
285
            }
286
287
            /* and show the animation root window to make everything visible */
288
34
            _gx_widget_show((GX_WIDGET *)root);
289
            /* The drawing status is deliberately kept out of the completion
290
               status of this function: _gx_widget_show() above releases the
291
               view list of the animation root window, so
292
               _gx_canvas_drawing_initiate() reports GX_NO_VIEWS here.  */
293
34
            draw_status = _gx_canvas_drawing_initiate(animation -> gx_animation_canvas, (GX_WIDGET *)root, &root -> gx_widget_size);
294
295
            /* Draw and complete only when a draw context was actually pushed.
296
               GX_DRAW_NESTING_EXCEEDED means no context was pushed, so calling
297
               _gx_canvas_drawing_complete() would corrupt the outer context.  */
298

34
            if ((draw_status == GX_SUCCESS) || (draw_status == GX_NO_VIEWS))
299
            {
300
34
                _gx_widget_children_draw((GX_WIDGET *)root);
301
34
                _gx_canvas_drawing_complete(animation -> gx_animation_canvas, GX_FALSE);
302
            }
303
304
            /* set the initial alpha and make our canvas visible */
305
34
            _gx_canvas_alpha_set(animation -> gx_animation_canvas, info -> gx_animation_start_alpha);
306
34
            _gx_canvas_show(animation -> gx_animation_canvas);
307
        }
308
    }
309
310
    /* Return completion status code. */
311
116
    return(GX_SUCCESS);
312
}
313
#endif