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