1 #include "demo_guix_smart_watch.h"
2 
3 #define CLOCK_SLIDE_SHIFT 40
4 
5 #define LINE_LENGTH 25
6 
7 #define TARGET_HOUR_MIN_XPOS 206
8 #define TARGET_HOUR_MIN_YPOS 132
9 #define TARGET_HOUR_MAX_XPOS (TARGET_HOUR_MIN_XPOS + CLOCK_SLIDE_SHIFT)
10 #define TARGET_HOUR_MAX_YPOS (TARGET_HOUR_MIN_YPOS + CLOCK_SLIDE_SHIFT)
11 
12 #define TARGET_MINIUTE_MIN_XPOS 211
13 #define TARGET_MINIUTE_MIN_YPOS 218
14 #define TARGET_MINIUTE_MAX_XPOS (TARGET_MINIUTE_MIN_XPOS + CLOCK_SLIDE_SHIFT)
15 #define TARGET_MINIUTE_MAX_YPOS (TARGET_MINIUTE_MIN_YPOS + CLOCK_SLIDE_SHIFT)
16 
17 /* Define clock slide animation control blocks. */
18 static GX_ANIMATION clock_slide_animation[2];
19 
20 /* Define local variable for background wave animation.  */
21 static INT wave_rotation_angle = 0;
22 
23 /******************************************************************************************/
24 /* Start clock slide animation.                                                           */
25 /******************************************************************************************/
clock_slide_animation_start()26 static void clock_slide_animation_start()
27 {
28     GX_ANIMATION_INFO info;
29     GX_WIDGET* target_hour = (GX_WIDGET*)&clock_5_screen.clock_5_screen_hour;
30     GX_WIDGET* target_minute = (GX_WIDGET*)&clock_5_screen.clock_5_screen_minute;
31     GX_POINT target_hour_end_pos;
32     GX_POINT target_minute_end_pos;
33 
34     if (target_hour->gx_widget_size.gx_rectangle_left < target_minute->gx_widget_size.gx_rectangle_left)
35     {
36         target_hour_end_pos.gx_point_x = TARGET_HOUR_MAX_XPOS;
37         target_hour_end_pos.gx_point_y = TARGET_HOUR_MAX_YPOS;
38         target_minute_end_pos.gx_point_x = TARGET_MINIUTE_MIN_XPOS;
39         target_minute_end_pos.gx_point_y = TARGET_MINIUTE_MIN_YPOS;
40     }
41     else
42     {
43         target_hour_end_pos.gx_point_x = TARGET_HOUR_MIN_XPOS;
44         target_hour_end_pos.gx_point_y = TARGET_HOUR_MIN_YPOS;
45         target_minute_end_pos.gx_point_x = TARGET_MINIUTE_MAX_XPOS;
46         target_minute_end_pos.gx_point_y = TARGET_MINIUTE_MAX_YPOS;
47     }
48 
49     memset(&info, 0, sizeof(GX_ANIMATION_INFO));
50     info.gx_animation_parent = (GX_WIDGET*)&clock_5_screen;
51     info.gx_animation_target = target_hour;
52     info.gx_animation_start_alpha = 255;
53     info.gx_animation_end_alpha = 255;
54     info.gx_animation_frame_interval = 40 / GX_SYSTEM_TIMER_MS;
55     info.gx_animation_id = CLOCK_SLIDE_ANIMATION_ID;
56     info.gx_animation_start_position.gx_point_x = target_hour->gx_widget_size.gx_rectangle_left;
57     info.gx_animation_start_position.gx_point_y = target_hour->gx_widget_size.gx_rectangle_top;
58     info.gx_animation_end_position = target_hour_end_pos;
59     info.gx_animation_steps = GX_ABS(info.gx_animation_end_position.gx_point_x - info.gx_animation_start_position.gx_point_x);
60 
61     gx_animation_start(&clock_slide_animation[0], &info);
62 
63     info.gx_animation_target = target_minute;
64     info.gx_animation_start_position.gx_point_x = target_minute->gx_widget_size.gx_rectangle_left;
65     info.gx_animation_start_position.gx_point_y = target_minute->gx_widget_size.gx_rectangle_top;
66     info.gx_animation_end_position = target_minute_end_pos;
67 
68     gx_animation_start(&clock_slide_animation[1], &info);
69 }
70 
71 /******************************************************************************************/
72 /* Stop clock slide animation.                                                            */
73 /******************************************************************************************/
clock_slide_animation_stop()74 static void clock_slide_animation_stop()
75 {
76     gx_animation_stop(&clock_slide_animation[0]);
77     gx_animation_stop(&clock_slide_animation[1]);
78 }
79 
80 /******************************************************************************************/
81 /* Override the default event processing of "clock_screen_template" to handle signals     */
82 /* from my child widgets.                                                                 */
83 /******************************************************************************************/
clock_5_screen_event_process(GX_WINDOW * window,GX_EVENT * event_ptr)84 UINT clock_5_screen_event_process(GX_WINDOW* window, GX_EVENT* event_ptr)
85 {
86     switch (event_ptr->gx_event_type)
87     {
88     case GX_EVENT_SHOW:
89         gx_animation_create(&clock_slide_animation[0]);
90         gx_animation_create(&clock_slide_animation[1]);
91         clear_screen_clock_record();
92         screen_clock_update(&clock_5_screen.clock_5_screen_hour, &clock_5_screen.clock_5_screen_minute, GX_NULL);
93         gx_system_timer_start(window, SCREEN_CLOCK_TIMER_ID, GX_TICKS_SECOND, GX_TICKS_SECOND);
94         return gx_window_event_process(window, event_ptr);
95 
96     case GX_EVENT_HIDE:
97         gx_system_timer_stop(window, SCREEN_CLOCK_TIMER_ID);
98         return gx_window_event_process(window, event_ptr);
99 
100     case USER_EVENT_ANIMATION_START:
101         gx_system_timer_start(window, SCREEN_ANIMATION_TIMER_ID, 20 / GX_SYSTEM_TIMER_MS, 20 / GX_SYSTEM_TIMER_MS);
102         clock_slide_animation_start();
103         break;
104 
105     case USER_EVENT_ANIMATION_STOP:
106         clock_slide_animation_stop();
107         gx_system_timer_stop(window, SCREEN_ANIMATION_TIMER_ID);
108         break;
109 
110     case GX_EVENT_ANIMATION_COMPLETE:
111         if (event_ptr->gx_event_sender == CLOCK_SLIDE_ANIMATION_ID)
112         {
113             clock_slide_animation_start();
114         }
115         break;
116 
117     case GX_EVENT_TIMER:
118         switch (event_ptr->gx_event_payload.gx_event_timer_id)
119         {
120         case SCREEN_CLOCK_TIMER_ID:
121             screen_clock_update(&clock_5_screen.clock_5_screen_hour, &clock_5_screen.clock_5_screen_minute, GX_NULL);
122             break;
123 
124         case SCREEN_ANIMATION_TIMER_ID:
125             wave_rotation_angle = (358 + wave_rotation_angle) % 360;
126 
127             gx_system_dirty_mark(window);
128             break;
129         }
130         break;
131 
132     default:
133         return gx_window_event_process(window, event_ptr);
134     }
135 
136     return 0;
137 }
138 
139 /******************************************************************************************/
140 /* Draw animation wave in the center of specified window.                                 */
141 /******************************************************************************************/
clock_5_screen_draw(GX_WINDOW * window)142 VOID clock_5_screen_draw(GX_WINDOW* window)
143 {
144     GX_RECTANGLE* size = &window->gx_widget_size;
145     INT scaled_angle;
146     INT xdist;
147     INT ydist;
148     INT xcenter;
149     INT ycenter;
150     INT width;
151     INT height;
152     GX_PIXELMAP* map;
153 
154     gx_window_background_draw(window);
155 
156     gx_context_pixelmap_get(GX_PIXELMAP_ID_WAVE, &map);
157 
158     width = size->gx_rectangle_right - size->gx_rectangle_left + 1;
159     height = size->gx_rectangle_bottom - size->gx_rectangle_top + 1;
160     xcenter = size->gx_rectangle_left + width * 3 / 5;
161     ycenter = size->gx_rectangle_top + height * 3 / 5;
162 
163     gx_context_brush_define(GX_COLOR_ID_BLUE, GX_COLOR_ID_BLUE, GX_BRUSH_ALIAS | GX_BRUSH_SOLID_FILL);
164     gx_context_brush_width_set(1);
165 
166     scaled_angle = GX_FIXED_VAL_MAKE(wave_rotation_angle);
167     xdist = GX_FIXED_VAL_TO_INT(gx_utility_math_cos(scaled_angle) * LINE_LENGTH);
168     ydist = GX_FIXED_VAL_TO_INT(gx_utility_math_sin(scaled_angle) * LINE_LENGTH);
169 
170     width >>= 1;
171     height >>= 1;
172 
173     gx_canvas_pixelmap_draw(xcenter + xdist - width, ycenter + ydist - height, map);
174 
175     scaled_angle = GX_FIXED_VAL_MAKE(wave_rotation_angle + 60);
176     xdist = GX_FIXED_VAL_TO_INT(gx_utility_math_cos(scaled_angle) * LINE_LENGTH);
177     ydist = GX_FIXED_VAL_TO_INT(gx_utility_math_sin(scaled_angle) * LINE_LENGTH);
178 
179     gx_canvas_pixelmap_draw(xcenter + xdist - width, ycenter + ydist - height, map);
180 
181     scaled_angle = GX_FIXED_VAL_MAKE(wave_rotation_angle + 120);
182     xdist = GX_FIXED_VAL_TO_INT(gx_utility_math_cos(scaled_angle) * LINE_LENGTH);
183     ydist = GX_FIXED_VAL_TO_INT(gx_utility_math_sin(scaled_angle) * LINE_LENGTH);
184 
185     gx_canvas_pixelmap_draw(xcenter + xdist - width, ycenter + ydist - height, map);
186 
187     gx_widget_children_draw(window);
188 }