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