1 /**************************************************************************/
2 /*                                                                        */
3 /*       Copyright (c) Microsoft Corporation. All rights reserved.        */
4 /*                                                                        */
5 /*       This software is licensed under the Microsoft Software License   */
6 /*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
7 /*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
8 /*       and in the root directory of this software.                      */
9 /*                                                                        */
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_system.h"
29 #include "gx_widget.h"
30 #include "gx_animation.h"
31 
32 
33 /**************************************************************************/
34 /*                                                                        */
35 /*  FUNCTION                                               RELEASE        */
36 /*                                                                        */
37 /*    _gx_animation_drag_event_check                      PORTABLE C      */
38 /*                                                           6.1.8        */
39 /*  AUTHOR                                                                */
40 /*                                                                        */
41 /*    Kenneth Maxwell, Microsoft Corporation                              */
42 /*                                                                        */
43 /*  DESCRIPTION                                                           */
44 /*                                                                        */
45 /*    Internal helper function that handles incoming events for screen    */
46 /*    drag animation.                                                     */
47 /*                                                                        */
48 /*  INPUT                                                                 */
49 /*                                                                        */
50 /*    animation                             Pointer to animation control  */
51 /*                                            block                       */
52 /*    event_ptr                             Event to process              */
53 /*                                                                        */
54 /*  OUTPUT                                                                */
55 /*                                                                        */
56 /*    status                                Completion status             */
57 /*                                                                        */
58 /*  CALLS                                                                 */
59 /*                                                                        */
60 /*    _gx_animation_slide_landing           Move animation screens one    */
61 /*                                            step toward target position */
62 /*    _gx_animation_slide_landing_start     Prepare for screen landing    */
63 /*    _gx_animation_drag_tracking_start     Prepare for screen slide      */
64 /*                                            animation                   */
65 /*    _gx_animation_drag_tracking           Shift animation screens       */
66 /*                                            accordion to pen pos        */
67 /*    _gx_system_event_send                 Send an event for processing  */
68 /*    _gx_system_input_capture              Temporarily direct all input  */
69 /*                                            events to specified widget  */
70 /*    _gx_system_input_release              Release captured input events */
71 /*    _gx_system_timer_stop                 Stop a timer for a widget     */
72 /*                                                                        */
73 /*  CALLED BY                                                             */
74 /*                                                                        */
75 /*    _gx_animation_drag_event_process                                    */
76 /*                                                                        */
77 /*  RELEASE HISTORY                                                       */
78 /*                                                                        */
79 /*    DATE              NAME                      DESCRIPTION             */
80 /*                                                                        */
81 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
82 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
83 /*                                            resulting in version 6.1    */
84 /*  08-02-2021     Kenneth Maxwell          Modified comment(s),          */
85 /*                                            replaced abs with GX_ABS,   */
86 /*                                            resulting in version 6.1.8  */
87 /*                                                                        */
88 /**************************************************************************/
_gx_animation_drag_event_check(GX_ANIMATION * animation,GX_EVENT * event_ptr)89 static UINT  _gx_animation_drag_event_check(GX_ANIMATION *animation, GX_EVENT *event_ptr)
90 {
91 GX_ANIMATION_INFO *info = &animation -> gx_animation_info;
92 GX_RECTANGLE      *size;
93 INT                delta;
94 INT                temp;
95 GX_WIDGET        **stackptr;
96 GX_EVENT           input_release_event;
97 INT                shift;
98 
99     switch (event_ptr -> gx_event_type)
100     {
101     case GX_EVENT_PEN_DOWN:
102         if (animation -> gx_animation_status == GX_ANIMATION_IDLE)
103         {
104             _gx_system_input_capture(info -> gx_animation_parent);
105 
106             /* Initiate animation information. */
107             animation -> gx_animation_status = GX_ANIMATION_SLIDE_TRACKING;
108 
109             if (info -> gx_animation_style & GX_ANIMATION_VERTICAL)
110             {
111                 animation -> gx_animation_slide_tracking_start_pos = event_ptr -> gx_event_payload.gx_event_pointdata.gx_point_y;
112                 animation -> gx_animation_slide_tracking_current_pos = event_ptr -> gx_event_payload.gx_event_pointdata.gx_point_y;
113             }
114             else
115             {
116                 animation -> gx_animation_slide_tracking_start_pos = event_ptr -> gx_event_payload.gx_event_pointdata.gx_point_x;
117                 animation -> gx_animation_slide_tracking_current_pos = event_ptr -> gx_event_payload.gx_event_pointdata.gx_point_x;
118             }
119             animation -> gx_animation_slide_target_index_1 = -1;
120             animation -> gx_animation_slide_target_index_2 = -1;
121         }
122         break;
123 
124     case GX_EVENT_PEN_DRAG:
125         if (animation -> gx_animation_status == GX_ANIMATION_SLIDE_TRACKING)
126         {
127             if (info -> gx_animation_style & GX_ANIMATION_VERTICAL)
128             {
129                 delta = GX_ABS(event_ptr -> gx_event_payload.gx_event_pointdata.gx_point_y - animation -> gx_animation_slide_tracking_start_pos);
130             }
131             else
132             {
133                 delta = GX_ABS(event_ptr -> gx_event_payload.gx_event_pointdata.gx_point_x - animation -> gx_animation_slide_tracking_start_pos);
134             }
135 
136             if ((animation -> gx_animation_slide_target_index_1 == -1) &&
137                 (delta > GX_ANIMATION_MIN_SLIDING_DIST))
138             {
139                 /* Start swiping, remove other widgets from input capture stack.  */
140                 stackptr = _gx_system_input_capture_stack;
141                 memset(&input_release_event, 0, sizeof(GX_EVENT));
142                 input_release_event.gx_event_type = GX_EVENT_INPUT_RELEASE;
143 
144                 while (*stackptr)
145                 {
146                     if (*stackptr != info -> gx_animation_parent)
147                     {
148                         input_release_event.gx_event_target = *stackptr;
149                         _gx_system_event_send(&input_release_event);
150                     }
151                     stackptr++;
152                 }
153 
154                 _gx_animation_drag_tracking_start(animation, event_ptr -> gx_event_payload.gx_event_pointdata);
155             }
156 
157              _gx_animation_drag_tracking(animation, event_ptr -> gx_event_payload.gx_event_pointdata);
158         }
159         break;
160 
161     case GX_EVENT_PEN_UP:
162         if (animation -> gx_animation_status == GX_ANIMATION_SLIDE_TRACKING)
163         {
164             _gx_system_input_release(info -> gx_animation_parent);
165             animation -> gx_animation_status = GX_ANIMATION_IDLE;
166 
167             size = &info -> gx_animation_parent -> gx_widget_size;
168 
169             delta = animation -> gx_animation_slide_tracking_current_pos - animation -> gx_animation_slide_tracking_start_pos;
170             if (info -> gx_animation_style & GX_ANIMATION_VERTICAL)
171             {
172                 shift = (size -> gx_rectangle_bottom - size -> gx_rectangle_top + 1) >> 1;
173             }
174             else
175             {
176                 shift = (size -> gx_rectangle_right - size -> gx_rectangle_left + 1) >> 1;
177             }
178 
179             if ((GX_ABS(delta) < shift) || (animation -> gx_animation_slide_target_index_2 == -1))
180             {
181                 /* slide back to original when slide distance is less than half screen width/height. */
182                 if (animation -> gx_animation_slide_target_index_2 >= 0)
183                 {
184                     temp = animation -> gx_animation_slide_target_index_1;
185                     animation -> gx_animation_slide_target_index_1 = animation -> gx_animation_slide_target_index_2;
186                     animation -> gx_animation_slide_target_index_2 = (GX_VALUE)temp;
187                 }
188 
189                 switch (animation -> gx_animation_slide_direction)
190                 {
191                 case GX_ANIMATION_SLIDE_LEFT:
192                     animation -> gx_animation_slide_direction = GX_ANIMATION_SLIDE_RIGHT;
193                     break;
194 
195                 case GX_ANIMATION_SLIDE_RIGHT:
196                     animation -> gx_animation_slide_direction = GX_ANIMATION_SLIDE_LEFT;
197                     break;
198 
199                 case GX_ANIMATION_SLIDE_UP:
200                     animation -> gx_animation_slide_direction = GX_ANIMATION_SLIDE_DOWN;
201                     break;
202 
203                 case GX_ANIMATION_SLIDE_DOWN:
204                     animation -> gx_animation_slide_direction = GX_ANIMATION_SLIDE_UP;
205                     break;
206                 }
207             }
208 
209             if (delta)
210             {
211                 _gx_animation_slide_landing_start(animation);
212             }
213         }
214         break;
215 
216     case GX_EVENT_HORIZONTAL_FLICK:
217     case GX_EVENT_VERTICAL_FLICK:
218         if (animation -> gx_animation_status == GX_ANIMATION_SLIDE_LANDING)
219         {
220             delta = event_ptr -> gx_event_payload.gx_event_intdata[0];
221 
222             if (((animation -> gx_animation_slide_direction == GX_ANIMATION_SLIDE_LEFT) && (delta > 0)) ||
223                 ((animation -> gx_animation_slide_direction == GX_ANIMATION_SLIDE_RIGHT) && (delta < 0)) ||
224                 ((animation -> gx_animation_slide_direction == GX_ANIMATION_SLIDE_UP) && (delta > 0)) ||
225                 ((animation -> gx_animation_slide_direction == GX_ANIMATION_SLIDE_DOWN) && (delta < 0)))
226             {
227                 /* landing direction is different to flick direction
228                    exchange targets */
229                 if (animation -> gx_animation_slide_target_index_2 >= 0)
230                 {
231                     temp = animation -> gx_animation_slide_target_index_1;
232                     animation -> gx_animation_slide_target_index_1 = animation -> gx_animation_slide_target_index_2;
233                     animation -> gx_animation_slide_target_index_2 = (GX_VALUE)temp;
234                 }
235 
236                 animation -> gx_animation_status = GX_ANIMATION_IDLE;
237 
238                 switch (animation -> gx_animation_slide_direction)
239                 {
240                 case GX_ANIMATION_SLIDE_LEFT:
241                     animation -> gx_animation_slide_direction = GX_ANIMATION_SLIDE_RIGHT;
242                     break;
243 
244                 case GX_ANIMATION_SLIDE_RIGHT:
245                     animation -> gx_animation_slide_direction = GX_ANIMATION_SLIDE_LEFT;
246                     break;
247 
248                 case GX_ANIMATION_SLIDE_UP:
249                     animation -> gx_animation_slide_direction = GX_ANIMATION_SLIDE_DOWN;
250                     break;
251 
252                 default:
253                     animation -> gx_animation_slide_direction = GX_ANIMATION_SLIDE_UP;
254                     break;
255                 }
256             }
257 
258             if (delta)
259             {
260                 _gx_animation_slide_landing_start(animation);
261             }
262         }
263         break;
264 
265     case GX_EVENT_TIMER:
266         if (event_ptr -> gx_event_payload.gx_event_timer_id == GX_ANIMATION_SLIDE_TIMER)
267         {
268             if (animation -> gx_animation_status != GX_ANIMATION_SLIDE_LANDING)
269             {
270                 _gx_system_timer_stop(info -> gx_animation_parent, GX_ANIMATION_SLIDE_TIMER);
271                 break;
272             }
273 
274             _gx_animation_slide_landing(animation);
275         }
276         break;
277     }
278 
279     return GX_SUCCESS;
280 }
281 
282 /**************************************************************************/
283 /*                                                                        */
284 /*  FUNCTION                                               RELEASE        */
285 /*                                                                        */
286 /*    _gx_animation_drag_event_process                    PORTABLE C      */
287 /*                                                           6.1          */
288 /*  AUTHOR                                                                */
289 /*                                                                        */
290 /*    Kenneth Maxwell, Microsoft Corporation                              */
291 /*                                                                        */
292 /*  DESCRIPTION                                                           */
293 /*                                                                        */
294 /*    This function handles incoming events for screen drag animation.    */
295 /*                                                                        */
296 /*  INPUT                                                                 */
297 /*                                                                        */
298 /*    widget                                Pointer to widget control     */
299 /*                                            block                       */
300 /*    event_ptr                             Event to process              */
301 /*                                                                        */
302 /*  OUTPUT                                                                */
303 /*                                                                        */
304 /*    status                                Completion status             */
305 /*                                                                        */
306 /*  CALLS                                                                 */
307 /*                                                                        */
308 /*    _gx_animation_slide_event_check       Handle incoming events for    */
309 /*                                            screen drag animation       */
310 /*                                                                        */
311 /*  CALLED BY                                                             */
312 /*                                                                        */
313 /*    GUIX Internal Code                                                  */
314 /*                                                                        */
315 /*  RELEASE HISTORY                                                       */
316 /*                                                                        */
317 /*    DATE              NAME                      DESCRIPTION             */
318 /*                                                                        */
319 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
320 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
321 /*                                            resulting in version 6.1    */
322 /*                                                                        */
323 /**************************************************************************/
_gx_animation_drag_event_process(GX_WIDGET * widget,GX_EVENT * event_ptr)324 UINT  _gx_animation_drag_event_process(GX_WIDGET *widget, GX_EVENT *event_ptr)
325 {
326 GX_ANIMATION *animation;
327 
328     animation = _gx_system_animation_list;
329 
330     while (animation)
331     {
332         if ((animation -> gx_animation_info.gx_animation_parent == widget) &&
333             (animation -> gx_animation_original_event_process_function))
334         {
335             _gx_animation_drag_event_check(animation, event_ptr);
336 
337             /* Call original event process function.  */
338             animation -> gx_animation_original_event_process_function(widget, event_ptr);
339         }
340 
341         animation = animation -> gx_animation_next;
342     }
343 
344     return GX_SUCCESS;
345 }
346 
347