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_animation.h"
30 #include "gx_system.h"
31 #include "gx_canvas.h"
32
33 /**************************************************************************/
34 /* */
35 /* FUNCTION RELEASE */
36 /* */
37 /* _gx_animation_drag_tracking_start PORTABLE C */
38 /* 6.1.11 */
39 /* AUTHOR */
40 /* */
41 /* Kenneth Maxwell, Microsoft Corporation */
42 /* */
43 /* DESCRIPTION */
44 /* */
45 /* This function prepares for screen slide animation. */
46 /* */
47 /* INPUT */
48 /* */
49 /* animation Pointer to animation control */
50 /* block */
51 /* */
52 /* OUTPUT */
53 /* */
54 /* status Completion status */
55 /* */
56 /* CALLS */
57 /* */
58 /* _gx_widget_resize Resize widget */
59 /* _gx_widget_attach Attach a widget to its parent */
60 /* */
61 /* CALLED BY */
62 /* */
63 /* _gx_animation_drag_event_check */
64 /* */
65 /* RELEASE HISTORY */
66 /* */
67 /* DATE NAME DESCRIPTION */
68 /* */
69 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
70 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
71 /* resulting in version 6.1 */
72 /* 04-25-2022 Ting Zhu Modified comment(s), */
73 /* added canvas support, */
74 /* resulting in version 6.1.11 */
75 /* */
76 /**************************************************************************/
_gx_animation_drag_tracking_start(GX_ANIMATION * animation,GX_POINT penpos)77 UINT _gx_animation_drag_tracking_start(GX_ANIMATION *animation, GX_POINT penpos)
78 {
79 GX_ANIMATION_INFO *info;
80 GX_RECTANGLE size;
81 INT width;
82 GX_WIDGET *target_1;
83 GX_WIDGET *target_2 = GX_NULL;
84 INT index;
85 INT current_pos;
86 GX_WINDOW_ROOT *root;
87 GX_VALUE left;
88 GX_VALUE top;
89 VOID (*active_display_area_set)(INT layer, GX_RECTANGLE *size);
90
91 info = &animation -> gx_animation_info;
92
93 target_1 = info -> gx_animation_slide_screen_list[0];
94 index = 0;
95
96 /* Search for visible screen, which is the first animation target. */
97 while (target_1)
98 {
99 if (target_1 -> gx_widget_status & GX_STATUS_VISIBLE)
100 {
101 animation -> gx_animation_slide_target_index_1 = (GX_VALUE)index;
102 }
103 index++;
104 target_1 = info -> gx_animation_slide_screen_list[index];
105 }
106
107 animation -> gx_animation_slide_screen_list_size = (USHORT)index;
108
109 if (animation -> gx_animation_slide_target_index_1 == -1)
110 {
111 return(GX_FAILURE);
112 }
113
114 if (info -> gx_animation_style & GX_ANIMATION_VERTICAL)
115 {
116 current_pos = penpos.gx_point_y;
117 }
118 else
119 {
120 current_pos = penpos.gx_point_x;
121 }
122
123 /* Find second animation target according to sliding direction. */
124 if (current_pos < animation -> gx_animation_slide_tracking_start_pos)
125 {
126 /* Sliding left/up. */
127 index = animation -> gx_animation_slide_target_index_1 + 1;
128
129 if ((index >= animation -> gx_animation_slide_screen_list_size) &&
130 (info -> gx_animation_style & GX_ANIMATION_WRAP))
131 {
132 index = 0;
133 }
134 }
135 else
136 {
137 /* Sliding right/down. */
138 index = animation -> gx_animation_slide_target_index_1 - 1;
139
140 if ((index < 0) && (info -> gx_animation_style & GX_ANIMATION_WRAP))
141 {
142 index = animation -> gx_animation_slide_screen_list_size - 1;
143 }
144 }
145
146 if (info -> gx_animation_style & GX_ANIMATION_VERTICAL)
147 {
148 if (current_pos < animation -> gx_animation_slide_tracking_start_pos)
149 {
150 animation -> gx_animation_slide_direction = GX_ANIMATION_SLIDE_UP;
151 }
152 else
153 {
154 animation -> gx_animation_slide_direction = GX_ANIMATION_SLIDE_DOWN;
155 }
156 }
157 else
158 {
159 if (current_pos < animation -> gx_animation_slide_tracking_start_pos)
160 {
161 animation -> gx_animation_slide_direction = GX_ANIMATION_SLIDE_LEFT;
162 }
163 else
164 {
165 animation -> gx_animation_slide_direction = GX_ANIMATION_SLIDE_RIGHT;
166 }
167 }
168
169 target_1 = info -> gx_animation_slide_screen_list[animation -> gx_animation_slide_target_index_1];
170
171 if ((index >= 0) && (index < animation -> gx_animation_slide_screen_list_size))
172 {
173 animation -> gx_animation_slide_target_index_2 = (GX_VALUE)(index);
174
175 target_2 = info -> gx_animation_slide_screen_list[index];
176
177 size = target_2 -> gx_widget_size;
178
179 if (info -> gx_animation_style & GX_ANIMATION_VERTICAL)
180 {
181 width = size.gx_rectangle_bottom - size.gx_rectangle_top + 1;
182
183 switch (animation -> gx_animation_slide_direction)
184 {
185 case GX_ANIMATION_SLIDE_UP:
186
187 /* Slide up. */
188 size.gx_rectangle_top = (GX_VALUE)(target_1 -> gx_widget_size.gx_rectangle_bottom + 1);
189 size.gx_rectangle_bottom = (GX_VALUE)(size.gx_rectangle_top + width - 1);
190 break;
191
192 default:
193 /* Slide down. */
194 size.gx_rectangle_bottom = (GX_VALUE)(target_1 -> gx_widget_size.gx_rectangle_top - 1);
195 size.gx_rectangle_top = (GX_VALUE)(size.gx_rectangle_bottom - width + 1);
196 break;
197 }
198 size.gx_rectangle_left = (GX_VALUE)target_1 -> gx_widget_size.gx_rectangle_left;
199 size.gx_rectangle_right = (GX_VALUE)target_1 -> gx_widget_size.gx_rectangle_right;
200 }
201 else
202 {
203 width = size.gx_rectangle_right - size.gx_rectangle_left + 1;
204
205 switch (animation -> gx_animation_slide_direction)
206 {
207 case GX_ANIMATION_SLIDE_LEFT:
208 /* Slide left. */
209 size.gx_rectangle_left = (GX_VALUE)(target_1 -> gx_widget_size.gx_rectangle_right + 1);
210 size.gx_rectangle_right = (GX_VALUE)(size.gx_rectangle_left + width - 1);
211 break;
212 default:
213 /* Slide right. */
214 size.gx_rectangle_right = (GX_VALUE)(target_1 -> gx_widget_size.gx_rectangle_left - 1);
215 size.gx_rectangle_left = (GX_VALUE)(size.gx_rectangle_right - width + 1);
216 break;
217 }
218
219 size.gx_rectangle_top = (GX_VALUE)target_1 -> gx_widget_size.gx_rectangle_top;
220 size.gx_rectangle_bottom = (GX_VALUE)target_1 -> gx_widget_size.gx_rectangle_bottom;
221 }
222
223 /* Resize the second animation target. */
224 _gx_widget_resize(target_2, &size);
225
226 if (!animation -> gx_animation_canvas)
227 {
228
229 /* Attach the second target to animation parent. */
230 _gx_widget_attach(info -> gx_animation_parent, target_2);
231 }
232 }
233 else
234 {
235 animation -> gx_animation_slide_target_index_2 = -1;
236 }
237
238 if (animation -> gx_animation_canvas)
239 {
240 /* Find animation root. */
241 root = _gx_system_root_window_created_list;
242 while (root && root -> gx_window_root_canvas != animation -> gx_animation_canvas)
243 {
244 root = (GX_WINDOW_ROOT *)root -> gx_widget_next;
245 }
246
247 if (animation -> gx_animation_slide_direction == GX_ANIMATION_SLIDE_UP ||
248 animation -> gx_animation_slide_direction == GX_ANIMATION_SLIDE_LEFT ||
249 (!target_2))
250 {
251 left = target_1 -> gx_widget_size.gx_rectangle_left;
252 top = target_1 -> gx_widget_size.gx_rectangle_top;
253 }
254 else
255 {
256 left = target_2 -> gx_widget_size.gx_rectangle_left;
257 top = target_2 -> gx_widget_size.gx_rectangle_top;
258 }
259
260 if (left || top)
261 {
262 _gx_widget_shift(target_1, (GX_VALUE)-left, (GX_VALUE)-top, GX_TRUE);
263
264 if (target_2)
265 {
266 _gx_widget_shift(target_2, (GX_VALUE)-left, (GX_VALUE)-top, GX_TRUE);
267 }
268 }
269
270 /* Position the canvas at the animation starting position. */
271 _gx_canvas_offset_set(animation -> gx_animation_canvas, left, top);
272
273 if (animation -> gx_animation_canvas -> gx_canvas_hardware_layer >= 0)
274 {
275 active_display_area_set = animation -> gx_animation_canvas -> gx_canvas_display -> gx_display_layer_services -> gx_display_layer_active_display_area_set;
276
277 if (active_display_area_set)
278 {
279 /* Set active display area as the animation parent widget size. */
280 active_display_area_set(animation -> gx_animation_canvas -> gx_canvas_hardware_layer, &info -> gx_animation_parent -> gx_widget_size);
281 }
282 }
283
284 if (root)
285 {
286 /* Link the target to the animation root window. */
287 _gx_widget_attach((GX_WIDGET *)root, target_1);
288
289 if (target_2)
290 {
291 _gx_widget_attach((GX_WIDGET *)root, target_2);
292 }
293
294 /* and show the animation root window to make everything visible */
295 _gx_widget_show((GX_WIDGET *)root);
296 _gx_canvas_drawing_initiate(animation -> gx_animation_canvas, (GX_WIDGET *)root, &root -> gx_widget_size);
297 _gx_widget_children_draw((GX_WIDGET *)root);
298 _gx_canvas_drawing_complete(animation -> gx_animation_canvas, GX_FALSE);
299
300 /* set the initial alpha and make our canvas visible */
301 _gx_canvas_alpha_set(animation -> gx_animation_canvas, info -> gx_animation_start_alpha);
302 _gx_canvas_show(animation -> gx_animation_canvas);
303 }
304 }
305
306 /* Return completion status code. */
307 return(GX_SUCCESS);
308 }
309
310