1 /***************************************************************************
2 * Copyright (c) 2024 Microsoft Corporation
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the MIT License which is available at
6 * https://opensource.org/licenses/MIT.
7 *
8 * SPDX-License-Identifier: MIT
9 **************************************************************************/
10
11
12 /**************************************************************************/
13 /**************************************************************************/
14 /** */
15 /** GUIX Component */
16 /** */
17 /** Animation Management (Animation) */
18 /** */
19 /**************************************************************************/
20
21 #define GX_SOURCE_CODE
22
23
24 /* Include necessary system files. */
25
26 #include "gx_api.h"
27 #include "gx_widget.h"
28 #include "gx_system.h"
29 #include "gx_canvas.h"
30 #include "gx_animation.h"
31
32 /**************************************************************************/
33 /* */
34 /* FUNCTION RELEASE */
35 /* */
36 /* _gx_animation_complete_event_send PORTABLE C */
37 /* 6.1 */
38 /* AUTHOR */
39 /* */
40 /* Kenneth Maxwell, Microsoft Corporation */
41 /* */
42 /* DESCRIPTION */
43 /* */
44 /* Internal helper function to send an animation complete event. */
45 /* */
46 /* */
47 /* INPUT */
48 /* */
49 /* animation Pointer to animation control */
50 /* block */
51 /* */
52 /* OUTPUT */
53 /* */
54 /* None */
55 /* */
56 /* CALLS */
57 /* */
58 /* _gx_system_event_send Send GUIX event */
59 /* */
60 /* CALLED BY */
61 /* */
62 /* _gx_animation_complete */
63 /* _gx_animation_slide_landing */
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 /* */
73 /**************************************************************************/
_gx_animation_complete_event_send(GX_ANIMATION * animation)74 VOID _gx_animation_complete_event_send(GX_ANIMATION *animation)
75 {
76 GX_EVENT complete_event;
77
78 if (animation -> gx_animation_info.gx_animation_id)
79 {
80 if (animation -> gx_animation_info.gx_animation_target)
81 {
82 complete_event.gx_event_target = animation -> gx_animation_info.gx_animation_target;
83 }
84 else
85 {
86 complete_event.gx_event_target = animation -> gx_animation_info.gx_animation_parent;
87 }
88
89 /* send event to notify the animation has been completed */
90
91 complete_event.gx_event_type = GX_EVENT_ANIMATION_COMPLETE;
92 complete_event.gx_event_sender = animation -> gx_animation_info.gx_animation_id;
93 _gx_system_event_send(&complete_event);
94 }
95 }
96
97
98
99 /**************************************************************************/
100 /* */
101 /* FUNCTION RELEASE */
102 /* */
103 /* _gx_animation_complete PORTABLE C */
104 /* 6.1.3 */
105 /* AUTHOR */
106 /* */
107 /* Kenneth Maxwell, Microsoft Corporation */
108 /* */
109 /* DESCRIPTION */
110 /* */
111 /* Called internally when an animation sequence is finished. */
112 /* */
113 /* */
114 /* INPUT */
115 /* */
116 /* animation Pointer to window control */
117 /* block */
118 /* */
119 /* OUTPUT */
120 /* */
121 /* None */
122 /* */
123 /* CALLS */
124 /* */
125 /* _gx_animation_stop Stop an animation */
126 /* _gx_widget_detach Detach a widget from its */
127 /* parent */
128 /* _gx_widget_hide Hide a widget */
129 /* _gx_widget_shift Shift a widget */
130 /* _gx_widget_attach Attach a widget to its parent */
131 /* _gx_system_event_send Send GUIX event */
132 /* */
133 /* CALLED BY */
134 /* */
135 /* _gx_animation_update */
136 /* */
137 /* RELEASE HISTORY */
138 /* */
139 /* DATE NAME DESCRIPTION */
140 /* */
141 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
142 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
143 /* resulting in version 6.1 */
144 /* 12-31-2020 Kenneth Maxwell Modified comment(s), */
145 /* improved logic, */
146 /* resulting in version 6.1.3 */
147 /* */
148 /**************************************************************************/
149
_gx_animation_complete(GX_ANIMATION * animation)150 VOID _gx_animation_complete(GX_ANIMATION *animation)
151 {
152 GX_WIDGET *target;
153 GX_VALUE xshift;
154 GX_VALUE yshift;
155
156 /* Remove animation from active list and assign idle status */
157 _gx_animation_stop(animation);
158
159 /* do final cleanup */
160 target = animation -> gx_animation_info.gx_animation_target;
161
162 if (animation -> gx_animation_canvas)
163 {
164 /* hide the animation root */
165 if (target -> gx_widget_parent)
166 {
167 _gx_widget_hide(target -> gx_widget_parent);
168 }
169
170 /* Hide animation target. */
171 _gx_widget_detach(target);
172
173 if (animation -> gx_animation_info.gx_animation_style & GX_ANIMATION_PUSH_STACK)
174 {
175 /* Push animation target to system screen stack. */
176 _gx_system_screen_stack_push(target);
177 }
178 else if (animation -> gx_animation_info.gx_animation_style & GX_ANIMATION_DETACH)
179 {
180 if (target -> gx_widget_status & GX_STATUS_STUDIO_CREATED)
181 {
182 _gx_widget_delete(target);
183 animation -> gx_animation_info.gx_animation_target = GX_NULL;
184 }
185 }
186 else
187 {
188 /* shift the target into final position */
189 _gx_widget_shift(animation -> gx_animation_info.gx_animation_target,
190 animation -> gx_animation_info.gx_animation_end_position.gx_point_x,
191 animation -> gx_animation_info.gx_animation_end_position.gx_point_y, GX_FALSE);
192
193 /* attach the widget to it's parent */
194 _gx_widget_attach(animation -> gx_animation_info.gx_animation_parent, target);
195 }
196 _gx_canvas_hide(animation -> gx_animation_canvas);
197 _gx_system_canvas_refresh();
198 }
199 else
200 {
201 #if defined(GX_BRUSH_ALPHA_SUPPORT)
202
203 if (animation -> gx_animation_info.gx_animation_start_alpha !=
204 animation -> gx_animation_info.gx_animation_end_alpha)
205 {
206 animation -> gx_animation_info.gx_animation_target -> gx_widget_style &= ~GX_STYLE_USE_LOCAL_ALPHA;
207 _gx_system_dirty_mark(animation -> gx_animation_info.gx_animation_target);
208 }
209 #endif
210
211 if (animation -> gx_animation_info.gx_animation_style & GX_ANIMATION_PUSH_STACK)
212 {
213 /* Push animation target to system screen stack. */
214 _gx_system_screen_stack_push(target);
215 }
216 else if (animation -> gx_animation_info.gx_animation_style & GX_ANIMATION_DETACH)
217 {
218 _gx_widget_hide(target);
219
220 /* if this target was created by the Studio generated code, then delete the widget here */
221 if (target -> gx_widget_status & GX_STATUS_STUDIO_CREATED)
222 {
223 _gx_widget_delete(target);
224 animation -> gx_animation_info.gx_animation_target = GX_NULL;
225 }
226 }
227 else
228 {
229 /* test for shift translation */
230 xshift = (GX_VALUE)(animation -> gx_animation_info.gx_animation_end_position.gx_point_x -
231 animation -> gx_animation_info.gx_animation_start_position.gx_point_x);
232
233 yshift = (GX_VALUE)(animation -> gx_animation_info.gx_animation_end_position.gx_point_y -
234 animation -> gx_animation_info.gx_animation_start_position.gx_point_y);
235
236 if (xshift || yshift)
237 {
238 xshift = (GX_VALUE)(animation -> gx_animation_info.gx_animation_end_position.gx_point_x -
239 target -> gx_widget_size.gx_rectangle_left);
240
241 yshift = (GX_VALUE)(animation -> gx_animation_info.gx_animation_end_position.gx_point_y -
242 target -> gx_widget_size.gx_rectangle_top);
243
244 /* shift the target into final position */
245 _gx_widget_shift(target, xshift, yshift, GX_TRUE);
246 }
247 }
248 }
249
250 _gx_animation_complete_event_send(animation);
251
252 /* If this animation came from the system pool, return it */
253 if (animation -> gx_animation_system_allocated)
254 {
255 _gx_system_animation_free(animation);
256 }
257 }
258
259