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