GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_animation_drag_event_process.c Lines: 107 107 100.0 %
Date: 2024-12-05 08:52:37 Branches: 75 75 100.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_system.h"
28
#include "gx_widget.h"
29
#include "gx_animation.h"
30
31
32
/**************************************************************************/
33
/*                                                                        */
34
/*  FUNCTION                                               RELEASE        */
35
/*                                                                        */
36
/*    _gx_animation_drag_event_check                      PORTABLE C      */
37
/*                                                           6.1.8        */
38
/*  AUTHOR                                                                */
39
/*                                                                        */
40
/*    Kenneth Maxwell, Microsoft Corporation                              */
41
/*                                                                        */
42
/*  DESCRIPTION                                                           */
43
/*                                                                        */
44
/*    Internal helper function that handles incoming events for screen    */
45
/*    drag animation.                                                     */
46
/*                                                                        */
47
/*  INPUT                                                                 */
48
/*                                                                        */
49
/*    animation                             Pointer to animation control  */
50
/*                                            block                       */
51
/*    event_ptr                             Event to process              */
52
/*                                                                        */
53
/*  OUTPUT                                                                */
54
/*                                                                        */
55
/*    status                                Completion status             */
56
/*                                                                        */
57
/*  CALLS                                                                 */
58
/*                                                                        */
59
/*    _gx_animation_slide_landing           Move animation screens one    */
60
/*                                            step toward target position */
61
/*    _gx_animation_slide_landing_start     Prepare for screen landing    */
62
/*    _gx_animation_drag_tracking_start     Prepare for screen slide      */
63
/*                                            animation                   */
64
/*    _gx_animation_drag_tracking           Shift animation screens       */
65
/*                                            accordion to pen pos        */
66
/*    _gx_system_event_send                 Send an event for processing  */
67
/*    _gx_system_input_capture              Temporarily direct all input  */
68
/*                                            events to specified widget  */
69
/*    _gx_system_input_release              Release captured input events */
70
/*    _gx_system_timer_stop                 Stop a timer for a widget     */
71
/*                                                                        */
72
/*  CALLED BY                                                             */
73
/*                                                                        */
74
/*    _gx_animation_drag_event_process                                    */
75
/*                                                                        */
76
/*  RELEASE HISTORY                                                       */
77
/*                                                                        */
78
/*    DATE              NAME                      DESCRIPTION             */
79
/*                                                                        */
80
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
81
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
82
/*                                            resulting in version 6.1    */
83
/*  08-02-2021     Kenneth Maxwell          Modified comment(s),          */
84
/*                                            replaced abs with GX_ABS,   */
85
/*                                            resulting in version 6.1.8  */
86
/*                                                                        */
87
/**************************************************************************/
88
1665
static UINT  _gx_animation_drag_event_check(GX_ANIMATION *animation, GX_EVENT *event_ptr)
89
{
90
1665
GX_ANIMATION_INFO *info = &animation -> gx_animation_info;
91
GX_RECTANGLE      *size;
92
INT                delta;
93
INT                temp;
94
GX_WIDGET        **stackptr;
95
GX_EVENT           input_release_event;
96
INT                shift;
97
98

1665
    switch (event_ptr -> gx_event_type)
99
    {
100
105
    case GX_EVENT_PEN_DOWN:
101
105
        if (animation -> gx_animation_status == GX_ANIMATION_IDLE)
102
        {
103
104
            _gx_system_input_capture(info -> gx_animation_parent);
104
105
            /* Initiate animation information. */
106
104
            animation -> gx_animation_status = GX_ANIMATION_SLIDE_TRACKING;
107
108
104
            if (info -> gx_animation_style & GX_ANIMATION_VERTICAL)
109
            {
110
46
                animation -> gx_animation_slide_tracking_start_pos = event_ptr -> gx_event_payload.gx_event_pointdata.gx_point_y;
111
46
                animation -> gx_animation_slide_tracking_current_pos = event_ptr -> gx_event_payload.gx_event_pointdata.gx_point_y;
112
            }
113
            else
114
            {
115
58
                animation -> gx_animation_slide_tracking_start_pos = event_ptr -> gx_event_payload.gx_event_pointdata.gx_point_x;
116
58
                animation -> gx_animation_slide_tracking_current_pos = event_ptr -> gx_event_payload.gx_event_pointdata.gx_point_x;
117
            }
118
104
            animation -> gx_animation_slide_target_index_1 = -1;
119
104
            animation -> gx_animation_slide_target_index_2 = -1;
120
        }
121
105
        break;
122
123
126
    case GX_EVENT_PEN_DRAG:
124
126
        if (animation -> gx_animation_status == GX_ANIMATION_SLIDE_TRACKING)
125
        {
126
125
            if (info -> gx_animation_style & GX_ANIMATION_VERTICAL)
127
            {
128
53
                delta = GX_ABS(event_ptr -> gx_event_payload.gx_event_pointdata.gx_point_y - animation -> gx_animation_slide_tracking_start_pos);
129
            }
130
            else
131
            {
132
72
                delta = GX_ABS(event_ptr -> gx_event_payload.gx_event_pointdata.gx_point_x - animation -> gx_animation_slide_tracking_start_pos);
133
            }
134
135

125
            if ((animation -> gx_animation_slide_target_index_1 == -1) &&
136
                (delta > GX_ANIMATION_MIN_SLIDING_DIST))
137
            {
138
                /* Start swiping, remove other widgets from input capture stack.  */
139
103
                stackptr = _gx_system_input_capture_stack;
140
103
                memset(&input_release_event, 0, sizeof(GX_EVENT));
141
103
                input_release_event.gx_event_type = GX_EVENT_INPUT_RELEASE;
142
143
298
                while (*stackptr)
144
                {
145
195
                    if (*stackptr != info -> gx_animation_parent)
146
                    {
147
92
                        input_release_event.gx_event_target = *stackptr;
148
92
                        _gx_system_event_send(&input_release_event);
149
                    }
150
195
                    stackptr++;
151
                }
152
153
103
                _gx_animation_drag_tracking_start(animation, event_ptr -> gx_event_payload.gx_event_pointdata);
154
            }
155
156
125
             _gx_animation_drag_tracking(animation, event_ptr -> gx_event_payload.gx_event_pointdata);
157
        }
158
126
        break;
159
160
107
    case GX_EVENT_PEN_UP:
161
107
        if (animation -> gx_animation_status == GX_ANIMATION_SLIDE_TRACKING)
162
        {
163
106
            _gx_system_input_release(info -> gx_animation_parent);
164
106
            animation -> gx_animation_status = GX_ANIMATION_IDLE;
165
166
106
            size = &info -> gx_animation_parent -> gx_widget_size;
167
168
106
            delta = animation -> gx_animation_slide_tracking_current_pos - animation -> gx_animation_slide_tracking_start_pos;
169
106
            if (info -> gx_animation_style & GX_ANIMATION_VERTICAL)
170
            {
171
48
                shift = (size -> gx_rectangle_bottom - size -> gx_rectangle_top + 1) >> 1;
172
            }
173
            else
174
            {
175
58
                shift = (size -> gx_rectangle_right - size -> gx_rectangle_left + 1) >> 1;
176
            }
177
178

106
            if ((GX_ABS(delta) < shift) || (animation -> gx_animation_slide_target_index_2 == -1))
179
            {
180
                /* slide back to original when slide distance is less than half screen width/height. */
181
90
                if (animation -> gx_animation_slide_target_index_2 >= 0)
182
                {
183
55
                    temp = animation -> gx_animation_slide_target_index_1;
184
55
                    animation -> gx_animation_slide_target_index_1 = animation -> gx_animation_slide_target_index_2;
185
55
                    animation -> gx_animation_slide_target_index_2 = (GX_VALUE)temp;
186
                }
187
188

90
                switch (animation -> gx_animation_slide_direction)
189
                {
190
26
                case GX_ANIMATION_SLIDE_LEFT:
191
26
                    animation -> gx_animation_slide_direction = GX_ANIMATION_SLIDE_RIGHT;
192
26
                    break;
193
194
22
                case GX_ANIMATION_SLIDE_RIGHT:
195
22
                    animation -> gx_animation_slide_direction = GX_ANIMATION_SLIDE_LEFT;
196
22
                    break;
197
198
26
                case GX_ANIMATION_SLIDE_UP:
199
26
                    animation -> gx_animation_slide_direction = GX_ANIMATION_SLIDE_DOWN;
200
26
                    break;
201
202
14
                case GX_ANIMATION_SLIDE_DOWN:
203
14
                    animation -> gx_animation_slide_direction = GX_ANIMATION_SLIDE_UP;
204
14
                    break;
205
                }
206
            }
207
208
106
            if (delta)
209
            {
210
104
                _gx_animation_slide_landing_start(animation);
211
            }
212
        }
213
107
        break;
214
215
46
    case GX_EVENT_HORIZONTAL_FLICK:
216
    case GX_EVENT_VERTICAL_FLICK:
217
46
        if (animation -> gx_animation_status == GX_ANIMATION_SLIDE_LANDING)
218
        {
219
44
            delta = event_ptr -> gx_event_payload.gx_event_intdata[0];
220
221

44
            if (((animation -> gx_animation_slide_direction == GX_ANIMATION_SLIDE_LEFT) && (delta > 0)) ||
222

37
                ((animation -> gx_animation_slide_direction == GX_ANIMATION_SLIDE_RIGHT) && (delta < 0)) ||
223

25
                ((animation -> gx_animation_slide_direction == GX_ANIMATION_SLIDE_UP) && (delta > 0)) ||
224

19
                ((animation -> gx_animation_slide_direction == GX_ANIMATION_SLIDE_DOWN) && (delta < 0)))
225
            {
226
                /* landing direction is different to flick direction
227
                   exchange targets */
228
37
                if (animation -> gx_animation_slide_target_index_2 >= 0)
229
                {
230
26
                    temp = animation -> gx_animation_slide_target_index_1;
231
26
                    animation -> gx_animation_slide_target_index_1 = animation -> gx_animation_slide_target_index_2;
232
26
                    animation -> gx_animation_slide_target_index_2 = (GX_VALUE)temp;
233
                }
234
235
37
                animation -> gx_animation_status = GX_ANIMATION_IDLE;
236
237

37
                switch (animation -> gx_animation_slide_direction)
238
                {
239
7
                case GX_ANIMATION_SLIDE_LEFT:
240
7
                    animation -> gx_animation_slide_direction = GX_ANIMATION_SLIDE_RIGHT;
241
7
                    break;
242
243
12
                case GX_ANIMATION_SLIDE_RIGHT:
244
12
                    animation -> gx_animation_slide_direction = GX_ANIMATION_SLIDE_LEFT;
245
12
                    break;
246
247
6
                case GX_ANIMATION_SLIDE_UP:
248
6
                    animation -> gx_animation_slide_direction = GX_ANIMATION_SLIDE_DOWN;
249
6
                    break;
250
251
12
                default:
252
12
                    animation -> gx_animation_slide_direction = GX_ANIMATION_SLIDE_UP;
253
12
                    break;
254
                }
255
            }
256
257
44
            if (delta)
258
            {
259
41
                _gx_animation_slide_landing_start(animation);
260
            }
261
        }
262
46
        break;
263
264
1042
    case GX_EVENT_TIMER:
265
1042
        if (event_ptr -> gx_event_payload.gx_event_timer_id == GX_ANIMATION_SLIDE_TIMER)
266
        {
267
1041
            if (animation -> gx_animation_status != GX_ANIMATION_SLIDE_LANDING)
268
            {
269
1
                _gx_system_timer_stop(info -> gx_animation_parent, GX_ANIMATION_SLIDE_TIMER);
270
1
                break;
271
            }
272
273
1040
            _gx_animation_slide_landing(animation);
274
        }
275
1041
        break;
276
    }
277
278
1665
    return GX_SUCCESS;
279
}
280
281
/**************************************************************************/
282
/*                                                                        */
283
/*  FUNCTION                                               RELEASE        */
284
/*                                                                        */
285
/*    _gx_animation_drag_event_process                    PORTABLE C      */
286
/*                                                           6.1          */
287
/*  AUTHOR                                                                */
288
/*                                                                        */
289
/*    Kenneth Maxwell, Microsoft Corporation                              */
290
/*                                                                        */
291
/*  DESCRIPTION                                                           */
292
/*                                                                        */
293
/*    This function handles incoming events for screen drag animation.    */
294
/*                                                                        */
295
/*  INPUT                                                                 */
296
/*                                                                        */
297
/*    widget                                Pointer to widget control     */
298
/*                                            block                       */
299
/*    event_ptr                             Event to process              */
300
/*                                                                        */
301
/*  OUTPUT                                                                */
302
/*                                                                        */
303
/*    status                                Completion status             */
304
/*                                                                        */
305
/*  CALLS                                                                 */
306
/*                                                                        */
307
/*    _gx_animation_slide_event_check       Handle incoming events for    */
308
/*                                            screen drag animation       */
309
/*                                                                        */
310
/*  CALLED BY                                                             */
311
/*                                                                        */
312
/*    GUIX Internal Code                                                  */
313
/*                                                                        */
314
/*  RELEASE HISTORY                                                       */
315
/*                                                                        */
316
/*    DATE              NAME                      DESCRIPTION             */
317
/*                                                                        */
318
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
319
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
320
/*                                            resulting in version 6.1    */
321
/*                                                                        */
322
/**************************************************************************/
323
1666
UINT  _gx_animation_drag_event_process(GX_WIDGET *widget, GX_EVENT *event_ptr)
324
{
325
GX_ANIMATION *animation;
326
327
1666
    animation = _gx_system_animation_list;
328
329
4992
    while (animation)
330
    {
331
3326
        if ((animation -> gx_animation_info.gx_animation_parent == widget) &&
332
1666
            (animation -> gx_animation_original_event_process_function))
333
        {
334
1665
            _gx_animation_drag_event_check(animation, event_ptr);
335
336
            /* Call original event process function.  */
337
1665
            animation -> gx_animation_original_event_process_function(widget, event_ptr);
338
        }
339
340
3326
        animation = animation -> gx_animation_next;
341
    }
342
343
1666
    return GX_SUCCESS;
344
}
345