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_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 /*  RELEASE HISTORY                                                       */
71 /*                                                                        */
72 /*    DATE              NAME                      DESCRIPTION             */
73 /*                                                                        */
74 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
75 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
76 /*                                            resulting in version 6.1    */
77 /*  04-25-2022     Ting Zhu                 Modified comment(s),          */
78 /*                                            added canvas and block move */
79 /*                                            support,                    */
80 /*                                            resulting in version 6.1.11 */
81 /*                                                                        */
82 /**************************************************************************/
_gx_animation_slide_landing(GX_ANIMATION * animation)83 UINT  _gx_animation_slide_landing(GX_ANIMATION *animation)
84 {
85 GX_ANIMATION_INFO *info = &animation -> gx_animation_info;
86 GX_WIDGET         *parent;
87 GX_WIDGET         *target_1 = GX_NULL;
88 GX_WIDGET         *target_2 = GX_NULL;
89 INT                x_shift = 0;
90 INT                y_shift = 0;
91 GX_RECTANGLE       target_size;
92 GX_RECTANGLE       block;
93 GX_VALUE           border_width;
94 
95     parent = animation -> gx_animation_info.gx_animation_parent;
96 
97     /* Get current animation targets. */
98     if (animation -> gx_animation_slide_target_index_1 >= 0)
99     {
100         target_1 = info -> gx_animation_slide_screen_list[animation -> gx_animation_slide_target_index_1];
101     }
102     else
103     {
104         /* Sliding animation should have 1 target at least, this should not happen. */
105 
106         /* Stop landing timer. */
107         _gx_system_timer_stop(parent, GX_ANIMATION_SLIDE_TIMER);
108 
109         return GX_FAILURE;
110     }
111 
112     if (animation -> gx_animation_slide_target_index_2 >= 0)
113     {
114         target_2 = info -> gx_animation_slide_screen_list[animation -> gx_animation_slide_target_index_2];
115     }
116 
117     if (target_2)
118     {
119         target_size = target_2 -> gx_widget_size;
120     }
121     else
122     {
123         target_size = target_1 -> gx_widget_size;
124     }
125 
126     if (animation -> gx_animation_canvas)
127     {
128         _gx_utility_rectangle_shift(&target_size, animation -> gx_animation_canvas -> gx_canvas_display_offset_x,
129                                     animation -> gx_animation_canvas -> gx_canvas_display_offset_y);
130     }
131 
132     if (info -> gx_animation_style & GX_ANIMATION_EASING_FUNC_MASK)
133     {
134         info -> gx_animation_steps = (GX_UBYTE)(info -> gx_animation_steps - 1);
135 
136         switch (animation -> gx_animation_slide_direction)
137         {
138         case GX_ANIMATION_SLIDE_LEFT:
139         case GX_ANIMATION_SLIDE_RIGHT:
140             _gx_utility_easing_function_calculate(info -> gx_animation_style,
141                                                   info -> gx_animation_start_position.gx_point_x,
142                                                   parent -> gx_widget_size.gx_rectangle_left,
143                                                   animation -> gx_animation_total_steps - info -> gx_animation_steps,
144                                                   animation -> gx_animation_total_steps, &x_shift);
145 
146             x_shift -= target_size.gx_rectangle_left;
147             break;
148 
149         default:
150             _gx_utility_easing_function_calculate(info -> gx_animation_style,
151                                                   info -> gx_animation_start_position.gx_point_y,
152                                                   parent -> gx_widget_size.gx_rectangle_top,
153                                                   animation -> gx_animation_total_steps - info -> gx_animation_steps,
154                                                   animation -> gx_animation_total_steps, &y_shift);
155 
156             y_shift -= target_size.gx_rectangle_top;
157             break;
158         }
159     }
160     else
161     {
162         /* Get landing shift value according to slide direction. */
163         switch (animation -> gx_animation_slide_direction)
164         {
165         case GX_ANIMATION_SLIDE_LEFT:
166             x_shift = -animation -> gx_animation_landing_speed;
167             break;
168 
169         case GX_ANIMATION_SLIDE_RIGHT:
170             x_shift = animation -> gx_animation_landing_speed;
171             break;
172 
173         case GX_ANIMATION_SLIDE_UP:
174             y_shift = -animation -> gx_animation_landing_speed;
175             break;
176 
177         default:
178             y_shift = animation -> gx_animation_landing_speed;
179             break;
180         }
181     }
182 
183     if (((info -> gx_animation_style & GX_ANIMATION_EASING_FUNC_MASK) && (info -> gx_animation_steps != 0)) ||
184         ((x_shift < 0) && ((GX_VALUE)(target_size.gx_rectangle_left + x_shift) > parent -> gx_widget_size.gx_rectangle_left)) ||
185         ((x_shift > 0) && ((GX_VALUE)(target_size.gx_rectangle_left + x_shift) < parent -> gx_widget_size.gx_rectangle_left)) ||
186         ((y_shift < 0) && ((GX_VALUE)(target_size.gx_rectangle_top + y_shift) > parent -> gx_widget_size.gx_rectangle_top)) ||
187         ((y_shift > 0) && ((GX_VALUE)(target_size.gx_rectangle_top + y_shift) < parent -> gx_widget_size.gx_rectangle_top)))
188     {
189         if (animation -> gx_animation_canvas)
190         {
191             _gx_canvas_offset_set(animation -> gx_animation_canvas,
192                                   (GX_VALUE)(animation -> gx_animation_canvas -> gx_canvas_display_offset_x + x_shift),
193                                   (GX_VALUE)(animation -> gx_animation_canvas -> gx_canvas_display_offset_y + y_shift));
194         }
195         else
196         {
197             /* Shift animation targets one step toward target position.  */
198 
199             if (info -> gx_animation_style & GX_ANIMATION_BLOCK_MOVE)
200             {
201                 _gx_widget_scroll_shift(target_1, (GX_VALUE)x_shift, (GX_VALUE)y_shift, GX_TRUE);
202 
203                 if (target_2)
204                 {
205                     _gx_widget_scroll_shift(target_2, (GX_VALUE)x_shift, (GX_VALUE)y_shift, GX_TRUE);
206                 }
207             }
208             else
209             {
210                 _gx_widget_shift(target_1, (GX_VALUE)x_shift, (GX_VALUE)y_shift, GX_TRUE);
211 
212                 if (target_2)
213                 {
214                     _gx_widget_shift(target_2, (GX_VALUE)x_shift, (GX_VALUE)y_shift, GX_TRUE);
215                 }
216             }
217         }
218     }
219     else
220     {
221         /* Shift animation targets to the target position. */
222 
223         /* Stop landing timer. */
224         _gx_system_timer_stop(parent, GX_ANIMATION_SLIDE_TIMER);
225 
226         /* Calculate the distance from current postion to final position. */
227         if (info -> gx_animation_style & GX_ANIMATION_VERTICAL)
228         {
229             y_shift = parent -> gx_widget_size.gx_rectangle_top - target_size.gx_rectangle_top;
230         }
231         else
232         {
233             x_shift = parent -> gx_widget_size.gx_rectangle_left - target_size.gx_rectangle_left;
234         }
235 
236         if (animation -> gx_animation_canvas)
237         {
238             /* hide the animation root */
239             if (target_1 -> gx_widget_parent)
240             {
241                 _gx_widget_hide(target_1 -> gx_widget_parent);
242             }
243 
244             /* attach the widget to it's parent */
245             if (target_2)
246             {
247                 _gx_widget_detach(target_1);
248                 target_1 = target_2;
249             }
250 
251             _gx_widget_shift(target_1,
252                              (GX_VALUE)(x_shift + animation -> gx_animation_canvas -> gx_canvas_display_offset_x),
253                              (GX_VALUE)(y_shift + animation -> gx_animation_canvas -> gx_canvas_display_offset_y), GX_TRUE);
254 
255             _gx_widget_attach(parent, target_1);
256 
257             _gx_canvas_hide(animation -> gx_animation_canvas);
258             _gx_system_canvas_refresh();
259         }
260         else
261         {
262             if (target_2)
263             {
264                 /* Detach the first target. */
265                 _gx_widget_detach(target_1);
266 
267                 target_1 = target_2;
268             }
269 
270             /* No second target, just move the first target to its final position. */
271             if (info -> gx_animation_style & GX_ANIMATION_BLOCK_MOVE)
272             {
273                 _gx_widget_scroll_shift(target_1, (GX_VALUE)x_shift, (GX_VALUE)y_shift, GX_TRUE);
274             }
275             else
276             {
277                 _gx_widget_shift(target_1, (GX_VALUE)x_shift, (GX_VALUE)y_shift, GX_TRUE);
278             }
279         }
280 
281         /* Reset animation information. */
282         animation -> gx_animation_slide_target_index_1 = -1;
283         animation -> gx_animation_slide_target_index_2 = -1;
284         animation -> gx_animation_status = GX_ANIMATION_IDLE;
285 
286         /* Send animation complete event.  */
287         _gx_animation_complete_event_send(animation);
288     }
289 
290     if (info -> gx_animation_style & GX_ANIMATION_BLOCK_MOVE)
291     {
292         _gx_widget_border_width_get(parent, &border_width);
293         _gx_widget_client_get(parent, border_width, &block);
294         _gx_widget_block_move(parent, &block, (GX_VALUE)x_shift, (GX_VALUE)y_shift);
295     }
296 
297     /* Return completion status code. */
298     return(GX_SUCCESS);
299 }
300 
301