1 #include "demo_guix_smart_watch.h"
2
3 #define CHART_SCROLL 4
4 #define CHART_Y_CENTER 30
5 #define EKG_COUNT 15
6 #define EKG_MAP_HEIGHT 50
7 #define EKG_MAP_WIDTH 255
8
9 #define ANIMATION_TOTAL_STEPS 20
10 #define CAL_ANIMATION_VAL(val) ((val) * animation_step / ANIMATION_TOTAL_STEPS)
11
12 extern GX_WINDOW_ROOT* root;
13
14 /* Define local variables. */
15 static GX_PIXELMAP ekg_map;
16 static GX_CANVAS ekg_canvas;
17 static GX_COLOR ekg_map_data_buffer[EKG_MAP_WIDTH * EKG_MAP_HEIGHT];
18
19 static INT ekg_line_start_y;
20 static INT ekg_line_end_y;
21 static INT ekg_index;
22 static INT ekg_values[EKG_COUNT] = { 0, 0, 0, 0, 0, 5, 7, 4, 1, 0, -16, 25, 18, -6, -1 };
23
24 static INT animation_step = 0;
25
26 /******************************************************************************************/
27 /* Initialize fitness screen. */
28 /******************************************************************************************/
fitness_screen_initialize()29 VOID fitness_screen_initialize()
30 {
31 memset(&ekg_map, 0, sizeof(GX_PIXELMAP));
32
33 ekg_map.gx_pixelmap_data = (GX_UBYTE*)ekg_map_data_buffer;
34 ekg_map.gx_pixelmap_data_size = sizeof(ekg_map_data_buffer);
35 ekg_map.gx_pixelmap_height = EKG_MAP_HEIGHT;
36 ekg_map.gx_pixelmap_width = EKG_MAP_WIDTH;
37 ekg_map.gx_pixelmap_format = GX_COLOR_FORMAT_24XRGB;
38
39 memset(&ekg_canvas, 0, sizeof(GX_CANVAS));
40
41 /* Create a canvas for drawing ekg. */
42 gx_canvas_create(&ekg_canvas, "ekg",
43 root->gx_window_root_canvas->gx_canvas_display, GX_CANVAS_SIMPLE,
44 EKG_MAP_WIDTH, EKG_MAP_HEIGHT, (GX_COLOR*)ekg_map.gx_pixelmap_data, ekg_map.gx_pixelmap_data_size);
45
46 ekg_line_start_y = CHART_Y_CENTER;
47 ekg_line_end_y = CHART_Y_CENTER;
48 ekg_index = 0;
49 }
50
51 /******************************************************************************************/
52 /* Reset screen data. */
53 /******************************************************************************************/
screen_data_reset()54 static void screen_data_reset()
55 {
56 gx_numeric_prompt_value_set(&fitness_screen.fitness_screen_running_steps, 0);
57 gx_numeric_prompt_value_set(&fitness_screen.fitness_screen_running_distance, 0);
58 gx_numeric_prompt_value_set(&fitness_screen.fitness_screen_calorie_burned_progress_val, 0);
59 gx_numeric_prompt_value_set(&fitness_screen.fitness_screen_running_progress_val, 0);
60 gx_numeric_prompt_value_set(&fitness_screen.fitness_screen_standing_progress_val, 0);
61 gx_radial_progress_bar_value_set(&fitness_screen.fitness_screen_calorie_burned_progress, 0);
62 gx_radial_progress_bar_value_set(&fitness_screen.fitness_screen_running_progress, 0);
63 gx_radial_progress_bar_value_set(&fitness_screen.fitness_screen_standing_progress, 0);
64 }
65
66 /******************************************************************************************/
67 /* Start a timer for animation. */
68 /******************************************************************************************/
animation_start(GX_WINDOW * window)69 static void animation_start(GX_WINDOW* window)
70 {
71 animation_step = 0;
72
73 gx_system_timer_start(window, SCREEN_ANIMATION_TIMER_ID, 40 / GX_SYSTEM_TIMER_MS, 40 / GX_SYSTEM_TIMER_MS);
74 }
75
76 /******************************************************************************************/
77 /* Update animation. */
78 /******************************************************************************************/
animation_update()79 static void animation_update()
80 {
81 INT val;
82
83 animation_step++;
84
85 val = get_running_steps();
86 gx_numeric_prompt_value_set(&fitness_screen.fitness_screen_running_steps, CAL_ANIMATION_VAL(val));
87
88 val = get_running_distance();
89 gx_numeric_prompt_value_set(&fitness_screen.fitness_screen_running_distance, CAL_ANIMATION_VAL(val));
90
91 val = get_calorie_burned_progress_val();
92 gx_numeric_prompt_value_set(&fitness_screen.fitness_screen_calorie_burned_progress_val, CAL_ANIMATION_VAL(val));
93
94 val = val * (-360) / 100;
95 gx_radial_progress_bar_value_set(&fitness_screen.fitness_screen_calorie_burned_progress, CAL_ANIMATION_VAL(val));
96
97 val = get_running_progress_val();
98 gx_numeric_prompt_value_set(&fitness_screen.fitness_screen_running_progress_val, CAL_ANIMATION_VAL(val));
99
100 val = val * (-360) / 100;
101 gx_radial_progress_bar_value_set(&fitness_screen.fitness_screen_running_progress, CAL_ANIMATION_VAL(val));
102
103 val = get_standing_progress_val();
104 gx_numeric_prompt_value_set(&fitness_screen.fitness_screen_standing_progress_val, CAL_ANIMATION_VAL(val));
105
106 val = val * (-360) / 100;
107 gx_radial_progress_bar_value_set(&fitness_screen.fitness_screen_standing_progress, CAL_ANIMATION_VAL(val));
108
109 if (animation_step == ANIMATION_TOTAL_STEPS)
110 {
111 gx_system_timer_stop(&fitness_screen, SCREEN_ANIMATION_TIMER_ID);
112 }
113 }
114
115
116 /******************************************************************************************/
117 /* Update ekg map. */
118 /******************************************************************************************/
ekg_map_update()119 static VOID ekg_map_update()
120 {
121 GX_RECTANGLE line_draw_rect;
122 GX_RECTANGLE canvas_size;
123
124 gx_utility_rectangle_define(&canvas_size, 0, 0, EKG_MAP_WIDTH - 1, EKG_MAP_HEIGHT - 1);
125 gx_utility_rectangle_define(&line_draw_rect, 0, 0, CHART_SCROLL - 1, EKG_MAP_HEIGHT - 1);
126
127 /* Initiate drawing on this canvas. */
128 gx_canvas_drawing_initiate(&ekg_canvas, GX_NULL, &canvas_size);
129 gx_canvas_block_move(&canvas_size, CHART_SCROLL, 0, GX_NULL);
130
131 /* Erase the rectangle ahead of the line */
132 gx_context_brush_define(GX_COLOR_ID_RED, GX_COLOR_ID_CANVAS, GX_BRUSH_SOLID_FILL | GX_BRUSH_ROUND | GX_BRUSH_ALIAS);
133 gx_context_brush_width_set(0);
134 gx_canvas_rectangle_draw(&line_draw_rect);
135
136 gx_context_brush_width_set(2);
137
138 ekg_line_end_y = ekg_line_start_y;
139 ekg_line_start_y = CHART_Y_CENTER - ekg_values[ekg_index];
140
141 gx_canvas_line_draw(0, ekg_line_start_y, CHART_SCROLL - 1, ekg_line_end_y);
142 gx_widget_shift(&fitness_screen.fitness_screen_ekg_dot_icon, 0, ekg_line_start_y - ekg_line_end_y, GX_TRUE);
143
144 /* Indicate that drawing on this canvas is complete. */
145 gx_canvas_drawing_complete(&ekg_canvas, GX_FALSE);
146
147 /* Mark waveform window as dirty. */
148 gx_system_dirty_mark((GX_WIDGET*)&fitness_screen.fitness_screen_ekg_waveform_win);
149
150 ekg_index++;
151
152 if (ekg_index >= EKG_COUNT)
153 {
154 ekg_index = 0;
155 }
156 }
157
158 /******************************************************************************************/
159 /* Override the default event processing of "fitness_screen" to handle signals from my */
160 /* child widgets. */
161 /******************************************************************************************/
fitness_screen_event_process(GX_WINDOW * window,GX_EVENT * event_ptr)162 UINT fitness_screen_event_process(GX_WINDOW *window, GX_EVENT *event_ptr)
163 {
164 switch (event_ptr->gx_event_type)
165 {
166 case GX_EVENT_SHOW:
167 screen_data_reset();
168 break;
169
170 case USER_EVENT_ANIMATION_START:
171 gx_system_timer_start(window, FITNESS_SCREEN_CHART_TIMER_ID, 100 / GX_SYSTEM_TIMER_MS, 100 / GX_SYSTEM_TIMER_MS);
172 animation_start(window);
173 break;
174
175 case USER_EVENT_ANIMATION_STOP:
176 gx_system_timer_stop(window, FITNESS_SCREEN_CHART_TIMER_ID);
177 gx_system_timer_stop(window, SCREEN_ANIMATION_TIMER_ID);
178 break;
179
180 case GX_EVENT_TIMER:
181 switch (event_ptr->gx_event_payload.gx_event_timer_id)
182 {
183 case FITNESS_SCREEN_CHART_TIMER_ID:
184 ekg_map_update();
185 break;
186
187 case SCREEN_ANIMATION_TIMER_ID:
188 animation_update();
189 break;
190 }
191 break;
192
193 case GX_SIGNAL(ID_CALORIE_BUTTON, GX_EVENT_CLICKED):
194 page_screen_slide((GX_WIDGET *)window, (GX_WIDGET *)&calories_screen);
195 break;
196
197 case GX_SIGNAL(ID_RUNNING_BUTTON, GX_EVENT_CLICKED):
198 page_screen_slide((GX_WIDGET *)window, (GX_WIDGET *)&run_screen);
199 break;
200
201 case GX_SIGNAL(ID_STANDING_BUTTON, GX_EVENT_CLICKED):
202 page_screen_slide((GX_WIDGET *)window, (GX_WIDGET *)&stand_screen);
203 break;
204
205 default:
206 break;
207 }
208
209 return screen_template_event_process(window, event_ptr);
210 }
211
212 /******************************************************************************************/
213 /* Override the default drawing of ekg waveform window. */
214 /******************************************************************************************/
ekg_waveform_win_draw(GX_WINDOW * window)215 VOID ekg_waveform_win_draw(GX_WINDOW* window)
216 {
217 GX_PIXELMAP *line_cover_gradient;
218 GX_RECTANGLE *size = &window->gx_widget_size;
219
220 /* Draw ekg waveform. */
221 gx_canvas_pixelmap_draw(size->gx_rectangle_left, size->gx_rectangle_top, &ekg_map);
222
223 /* Pick line cover gradient map. */
224 gx_context_pixelmap_get(GX_PIXELMAP_ID_LANDING_EKG_LINE_COVER_GRADIENT, &line_cover_gradient);
225
226 /* Draw line cover gradient map. */
227 gx_canvas_pixelmap_draw(size->gx_rectangle_right - line_cover_gradient->gx_pixelmap_width + 1, size->gx_rectangle_top, line_cover_gradient);
228 }