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 }