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_animation.h"
29 #include "gx_canvas.h"
30 
31 /**************************************************************************/
32 /*                                                                        */
33 /*  FUNCTION                                               RELEASE        */
34 /*                                                                        */
35 /*    _gx_animation_drag_tracking                         PORTABLE C      */
36 /*                                                           6.1.11       */
37 /*  AUTHOR                                                                */
38 /*                                                                        */
39 /*    Kenneth Maxwell, Microsoft Corporation                              */
40 /*                                                                        */
41 /*  DESCRIPTION                                                           */
42 /*                                                                        */
43 /*    This function moves the animation screens according to current pen  */
44 /*      position.                                                         */
45 /*                                                                        */
46 /*  INPUT                                                                 */
47 /*                                                                        */
48 /*    animation                             Pointer to animation control  */
49 /*                                            block                       */
50 /*    penpos                                Current pen position          */
51 /*                                                                        */
52 /*  OUTPUT                                                                */
53 /*                                                                        */
54 /*    status                                Completion status             */
55 /*                                                                        */
56 /*  CALLS                                                                 */
57 /*                                                                        */
58 /*    _gx_widget_detach                     Detach a widget from its      */
59 /*                                            parent                      */
60 /*    _gx_widget_shift                      Change widget's position      */
61 /*    _gx_animation_drag_tracking_start     Prepare for screen draw       */
62 /*                                            animation                   */
63 /*                                                                        */
64 /*  CALLED BY                                                             */
65 /*                                                                        */
66 /*    _gx_animation_drag_event_check                                      */
67 /*                                                                        */
68 /*  RELEASE HISTORY                                                       */
69 /*                                                                        */
70 /*    DATE              NAME                      DESCRIPTION             */
71 /*                                                                        */
72 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
73 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
74 /*                                            resulting in version 6.1    */
75 /*  04-25-2022     Ting Zhu                 Modified comment(s),          */
76 /*                                            added canvas and block move */
77 /*                                            support,                    */
78 /*                                            resulting in version 6.1.11 */
79 /*                                                                        */
80 /**************************************************************************/
_gx_animation_drag_tracking(GX_ANIMATION * animation,GX_POINT penpos)81 UINT  _gx_animation_drag_tracking(GX_ANIMATION *animation, GX_POINT penpos)
82 {
83 GX_VALUE     delta_x = 0;
84 GX_VALUE     delta_y = 0;
85 GX_VALUE     shift_x = 0;
86 GX_VALUE     shift_y = 0;
87 GX_VALUE     last_pos;
88 GX_VALUE     start_pos;
89 GX_VALUE     pen_pos;
90 GX_WIDGET   *target_1 = GX_NULL;
91 GX_WIDGET   *target_2 = GX_NULL;
92 GX_WIDGET   *parent;
93 GX_RECTANGLE block;
94 GX_VALUE     border_width;
95 
96     if (animation -> gx_animation_slide_target_index_1 >= 0)
97     {
98         target_1 = animation -> gx_animation_info.gx_animation_slide_screen_list[animation -> gx_animation_slide_target_index_1];
99     }
100 
101     if (target_1 == GX_NULL)
102     {
103         return GX_SUCCESS;
104     }
105 
106     if (animation -> gx_animation_slide_target_index_2 >= 0)
107     {
108         target_2 = animation -> gx_animation_info.gx_animation_slide_screen_list[animation -> gx_animation_slide_target_index_2];
109     }
110 
111     last_pos = animation -> gx_animation_slide_tracking_current_pos;
112     if (animation -> gx_animation_info.gx_animation_style & GX_ANIMATION_VERTICAL)
113     {
114         pen_pos = penpos.gx_point_y;
115         delta_y = (GX_VALUE)(pen_pos - last_pos);
116     }
117     else
118     {
119         pen_pos = penpos.gx_point_x;
120         delta_x = (GX_VALUE)(pen_pos - last_pos);
121     }
122 
123     if (delta_x || delta_y)
124     {
125         /* Calculate sliding distance. */
126         start_pos = animation -> gx_animation_slide_tracking_start_pos;
127 
128         if (((animation -> gx_animation_slide_direction == GX_ANIMATION_SLIDE_LEFT) && (pen_pos > start_pos)) ||
129             ((animation -> gx_animation_slide_direction == GX_ANIMATION_SLIDE_RIGHT) && (pen_pos < start_pos)) ||
130             ((animation -> gx_animation_slide_direction == GX_ANIMATION_SLIDE_UP) && (pen_pos > start_pos)) ||
131             ((animation -> gx_animation_slide_direction == GX_ANIMATION_SLIDE_DOWN) && (pen_pos < start_pos)))
132         {
133             /* Sliding direction changed, detach the second animation target and
134                call tracking start again.  */
135             if (target_2)
136             {
137                 _gx_widget_detach(target_2);
138             }
139 
140             if (animation -> gx_animation_canvas)
141             {
142                 _gx_widget_shift(target_1,
143                                  animation -> gx_animation_canvas -> gx_canvas_display_offset_x,
144                                  animation -> gx_animation_canvas -> gx_canvas_display_offset_y, GX_TRUE);
145             }
146 
147             _gx_animation_drag_tracking_start(animation, penpos);
148 
149             if (animation -> gx_animation_slide_target_index_2 >= 0)
150             {
151                 target_2 = animation -> gx_animation_info.gx_animation_slide_screen_list[animation -> gx_animation_slide_target_index_2];
152             }
153             else
154             {
155                 target_2 = GX_NULL;
156             }
157 
158             if (animation -> gx_animation_info.gx_animation_style & GX_ANIMATION_VERTICAL)
159             {
160                 shift_y = (GX_VALUE)(start_pos - last_pos);
161                 delta_y = (GX_VALUE)(pen_pos - start_pos);
162             }
163             else
164             {
165                 shift_x = (GX_VALUE)(start_pos - last_pos);
166                 delta_x = (GX_VALUE)(pen_pos - start_pos);
167             }
168         }
169 
170         if (!target_2)
171         {
172             if (animation -> gx_animation_info.gx_animation_style & GX_ANIMATION_VERTICAL)
173             {
174                 animation -> gx_animation_slide_tracking_start_pos = (GX_VALUE)(animation -> gx_animation_slide_tracking_start_pos + ((delta_y + 1) >> 1));
175                 delta_y >>= 1;
176             }
177             else
178             {
179                 animation -> gx_animation_slide_tracking_start_pos = (GX_VALUE)(animation -> gx_animation_slide_tracking_start_pos + ((delta_x + 1) >> 1));
180                 delta_x >>= 1;
181             }
182         }
183 
184         if (animation -> gx_animation_canvas)
185         {
186             /* adjust canvas offset */
187             _gx_canvas_offset_set(animation -> gx_animation_canvas,
188                                   (GX_VALUE)(animation -> gx_animation_canvas -> gx_canvas_display_offset_x + shift_x + delta_x),
189                                   (GX_VALUE)(animation -> gx_animation_canvas -> gx_canvas_display_offset_y + shift_y + delta_y));
190         }
191         else
192         {
193             if (animation -> gx_animation_info.gx_animation_style & GX_ANIMATION_BLOCK_MOVE)
194             {
195                 if (target_2)
196                 {
197                     _gx_widget_scroll_shift(target_2, (GX_VALUE)(shift_x + delta_x), (GX_VALUE)(shift_y + delta_y), GX_TRUE);
198                 }
199 
200                 _gx_widget_scroll_shift(target_1, (GX_VALUE)(shift_x + delta_x), (GX_VALUE)(shift_y + delta_y), GX_TRUE);
201 
202                 parent = animation -> gx_animation_info.gx_animation_parent;
203                 _gx_widget_border_width_get(parent, &border_width);
204                 _gx_widget_client_get(parent, border_width, &block);
205                 _gx_widget_block_move(parent, &block, (GX_VALUE)(shift_x + delta_x), (GX_VALUE)(shift_y + delta_y));
206             }
207             else
208             {
209                 if (target_2)
210                 {
211                     _gx_widget_shift(target_2, (GX_VALUE)(shift_x + delta_x), (GX_VALUE)(shift_y + delta_y), GX_TRUE);
212                 }
213 
214                 _gx_widget_shift(target_1, (GX_VALUE)(shift_x + delta_x), (GX_VALUE)(shift_y + delta_y), GX_TRUE);
215             }
216         }
217 
218         animation -> gx_animation_slide_tracking_current_pos = pen_pos;
219     }
220 
221     /* Return completion status code. */
222     return(GX_SUCCESS);
223 }
224 
225