mirror of
https://github.com/azure-rtos/guix.git
synced 2025-01-28 07:03:11 +08:00
228 lines
9.0 KiB
C
228 lines
9.0 KiB
C
#include "demo_guix_smart_watch.h"
|
|
|
|
#define CHART_SCROLL 4
|
|
#define CHART_Y_CENTER 30
|
|
#define EKG_COUNT 15
|
|
#define EKG_MAP_HEIGHT 50
|
|
#define EKG_MAP_WIDTH 255
|
|
|
|
#define ANIMATION_TOTAL_STEPS 20
|
|
#define CAL_ANIMATION_VAL(val) ((val) * animation_step / ANIMATION_TOTAL_STEPS)
|
|
|
|
extern GX_WINDOW_ROOT* root;
|
|
|
|
/* Define local variables. */
|
|
static GX_PIXELMAP ekg_map;
|
|
static GX_CANVAS ekg_canvas;
|
|
static GX_COLOR ekg_map_data_buffer[EKG_MAP_WIDTH * EKG_MAP_HEIGHT];
|
|
|
|
static INT ekg_line_start_y;
|
|
static INT ekg_line_end_y;
|
|
static INT ekg_index;
|
|
static INT ekg_values[EKG_COUNT] = { 0, 0, 0, 0, 0, 5, 7, 4, 1, 0, -16, 25, 18, -6, -1 };
|
|
|
|
static INT animation_step = 0;
|
|
|
|
/******************************************************************************************/
|
|
/* Initialize fitness screen. */
|
|
/******************************************************************************************/
|
|
VOID fitness_screen_initialize()
|
|
{
|
|
memset(&ekg_map, 0, sizeof(GX_PIXELMAP));
|
|
|
|
ekg_map.gx_pixelmap_data = (GX_UBYTE*)ekg_map_data_buffer;
|
|
ekg_map.gx_pixelmap_data_size = sizeof(ekg_map_data_buffer);
|
|
ekg_map.gx_pixelmap_height = EKG_MAP_HEIGHT;
|
|
ekg_map.gx_pixelmap_width = EKG_MAP_WIDTH;
|
|
ekg_map.gx_pixelmap_format = GX_COLOR_FORMAT_24XRGB;
|
|
|
|
memset(&ekg_canvas, 0, sizeof(GX_CANVAS));
|
|
|
|
/* Create a canvas for drawing ekg. */
|
|
gx_canvas_create(&ekg_canvas, "ekg",
|
|
root->gx_window_root_canvas->gx_canvas_display, GX_CANVAS_SIMPLE,
|
|
EKG_MAP_WIDTH, EKG_MAP_HEIGHT, (GX_COLOR*)ekg_map.gx_pixelmap_data, ekg_map.gx_pixelmap_data_size);
|
|
|
|
ekg_line_start_y = CHART_Y_CENTER;
|
|
ekg_line_end_y = CHART_Y_CENTER;
|
|
ekg_index = 0;
|
|
}
|
|
|
|
/******************************************************************************************/
|
|
/* Reset screen data. */
|
|
/******************************************************************************************/
|
|
static void screen_data_reset()
|
|
{
|
|
gx_numeric_prompt_value_set(&fitness_screen.fitness_screen_running_steps, 0);
|
|
gx_numeric_prompt_value_set(&fitness_screen.fitness_screen_running_distance, 0);
|
|
gx_numeric_prompt_value_set(&fitness_screen.fitness_screen_calorie_burned_progress_val, 0);
|
|
gx_numeric_prompt_value_set(&fitness_screen.fitness_screen_running_progress_val, 0);
|
|
gx_numeric_prompt_value_set(&fitness_screen.fitness_screen_standing_progress_val, 0);
|
|
gx_radial_progress_bar_value_set(&fitness_screen.fitness_screen_calorie_burned_progress, 0);
|
|
gx_radial_progress_bar_value_set(&fitness_screen.fitness_screen_running_progress, 0);
|
|
gx_radial_progress_bar_value_set(&fitness_screen.fitness_screen_standing_progress, 0);
|
|
}
|
|
|
|
/******************************************************************************************/
|
|
/* Start a timer for animation. */
|
|
/******************************************************************************************/
|
|
static void animation_start(GX_WINDOW* window)
|
|
{
|
|
animation_step = 0;
|
|
|
|
gx_system_timer_start(window, SCREEN_ANIMATION_TIMER_ID, 40 / GX_SYSTEM_TIMER_MS, 40 / GX_SYSTEM_TIMER_MS);
|
|
}
|
|
|
|
/******************************************************************************************/
|
|
/* Update animation. */
|
|
/******************************************************************************************/
|
|
static void animation_update()
|
|
{
|
|
INT val;
|
|
|
|
animation_step++;
|
|
|
|
val = get_running_steps();
|
|
gx_numeric_prompt_value_set(&fitness_screen.fitness_screen_running_steps, CAL_ANIMATION_VAL(val));
|
|
|
|
val = get_running_distance();
|
|
gx_numeric_prompt_value_set(&fitness_screen.fitness_screen_running_distance, CAL_ANIMATION_VAL(val));
|
|
|
|
val = get_calorie_burned_progress_val();
|
|
gx_numeric_prompt_value_set(&fitness_screen.fitness_screen_calorie_burned_progress_val, CAL_ANIMATION_VAL(val));
|
|
|
|
val = val * (-360) / 100;
|
|
gx_radial_progress_bar_value_set(&fitness_screen.fitness_screen_calorie_burned_progress, CAL_ANIMATION_VAL(val));
|
|
|
|
val = get_running_progress_val();
|
|
gx_numeric_prompt_value_set(&fitness_screen.fitness_screen_running_progress_val, CAL_ANIMATION_VAL(val));
|
|
|
|
val = val * (-360) / 100;
|
|
gx_radial_progress_bar_value_set(&fitness_screen.fitness_screen_running_progress, CAL_ANIMATION_VAL(val));
|
|
|
|
val = get_standing_progress_val();
|
|
gx_numeric_prompt_value_set(&fitness_screen.fitness_screen_standing_progress_val, CAL_ANIMATION_VAL(val));
|
|
|
|
val = val * (-360) / 100;
|
|
gx_radial_progress_bar_value_set(&fitness_screen.fitness_screen_standing_progress, CAL_ANIMATION_VAL(val));
|
|
|
|
if (animation_step == ANIMATION_TOTAL_STEPS)
|
|
{
|
|
gx_system_timer_stop(&fitness_screen, SCREEN_ANIMATION_TIMER_ID);
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************************************/
|
|
/* Update ekg map. */
|
|
/******************************************************************************************/
|
|
static VOID ekg_map_update()
|
|
{
|
|
GX_RECTANGLE line_draw_rect;
|
|
GX_RECTANGLE canvas_size;
|
|
|
|
gx_utility_rectangle_define(&canvas_size, 0, 0, EKG_MAP_WIDTH - 1, EKG_MAP_HEIGHT - 1);
|
|
gx_utility_rectangle_define(&line_draw_rect, 0, 0, CHART_SCROLL - 1, EKG_MAP_HEIGHT - 1);
|
|
|
|
/* Initiate drawing on this canvas. */
|
|
gx_canvas_drawing_initiate(&ekg_canvas, GX_NULL, &canvas_size);
|
|
gx_canvas_block_move(&canvas_size, CHART_SCROLL, 0, GX_NULL);
|
|
|
|
/* Erase the rectangle ahead of the line */
|
|
gx_context_brush_define(GX_COLOR_ID_RED, GX_COLOR_ID_CANVAS, GX_BRUSH_SOLID_FILL | GX_BRUSH_ROUND | GX_BRUSH_ALIAS);
|
|
gx_context_brush_width_set(0);
|
|
gx_canvas_rectangle_draw(&line_draw_rect);
|
|
|
|
gx_context_brush_width_set(2);
|
|
|
|
ekg_line_end_y = ekg_line_start_y;
|
|
ekg_line_start_y = CHART_Y_CENTER - ekg_values[ekg_index];
|
|
|
|
gx_canvas_line_draw(0, ekg_line_start_y, CHART_SCROLL - 1, ekg_line_end_y);
|
|
gx_widget_shift(&fitness_screen.fitness_screen_ekg_dot_icon, 0, ekg_line_start_y - ekg_line_end_y, GX_TRUE);
|
|
|
|
/* Indicate that drawing on this canvas is complete. */
|
|
gx_canvas_drawing_complete(&ekg_canvas, GX_FALSE);
|
|
|
|
/* Mark waveform window as dirty. */
|
|
gx_system_dirty_mark((GX_WIDGET*)&fitness_screen.fitness_screen_ekg_waveform_win);
|
|
|
|
ekg_index++;
|
|
|
|
if (ekg_index >= EKG_COUNT)
|
|
{
|
|
ekg_index = 0;
|
|
}
|
|
}
|
|
|
|
/******************************************************************************************/
|
|
/* Override the default event processing of "fitness_screen" to handle signals from my */
|
|
/* child widgets. */
|
|
/******************************************************************************************/
|
|
UINT fitness_screen_event_process(GX_WINDOW *window, GX_EVENT *event_ptr)
|
|
{
|
|
switch (event_ptr->gx_event_type)
|
|
{
|
|
case GX_EVENT_SHOW:
|
|
screen_data_reset();
|
|
break;
|
|
|
|
case USER_EVENT_ANIMATION_START:
|
|
gx_system_timer_start(window, FITNESS_SCREEN_CHART_TIMER_ID, 100 / GX_SYSTEM_TIMER_MS, 100 / GX_SYSTEM_TIMER_MS);
|
|
animation_start(window);
|
|
break;
|
|
|
|
case USER_EVENT_ANIMATION_STOP:
|
|
gx_system_timer_stop(window, FITNESS_SCREEN_CHART_TIMER_ID);
|
|
gx_system_timer_stop(window, SCREEN_ANIMATION_TIMER_ID);
|
|
break;
|
|
|
|
case GX_EVENT_TIMER:
|
|
switch (event_ptr->gx_event_payload.gx_event_timer_id)
|
|
{
|
|
case FITNESS_SCREEN_CHART_TIMER_ID:
|
|
ekg_map_update();
|
|
break;
|
|
|
|
case SCREEN_ANIMATION_TIMER_ID:
|
|
animation_update();
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case GX_SIGNAL(ID_CALORIE_BUTTON, GX_EVENT_CLICKED):
|
|
page_screen_slide((GX_WIDGET *)window, (GX_WIDGET *)&calories_screen);
|
|
break;
|
|
|
|
case GX_SIGNAL(ID_RUNNING_BUTTON, GX_EVENT_CLICKED):
|
|
page_screen_slide((GX_WIDGET *)window, (GX_WIDGET *)&run_screen);
|
|
break;
|
|
|
|
case GX_SIGNAL(ID_STANDING_BUTTON, GX_EVENT_CLICKED):
|
|
page_screen_slide((GX_WIDGET *)window, (GX_WIDGET *)&stand_screen);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return screen_template_event_process(window, event_ptr);
|
|
}
|
|
|
|
/******************************************************************************************/
|
|
/* Override the default drawing of ekg waveform window. */
|
|
/******************************************************************************************/
|
|
VOID ekg_waveform_win_draw(GX_WINDOW* window)
|
|
{
|
|
GX_PIXELMAP *line_cover_gradient;
|
|
GX_RECTANGLE *size = &window->gx_widget_size;
|
|
|
|
/* Draw ekg waveform. */
|
|
gx_canvas_pixelmap_draw(size->gx_rectangle_left, size->gx_rectangle_top, &ekg_map);
|
|
|
|
/* Pick line cover gradient map. */
|
|
gx_context_pixelmap_get(GX_PIXELMAP_ID_LANDING_EKG_LINE_COVER_GRADIENT, &line_cover_gradient);
|
|
|
|
/* Draw line cover gradient map. */
|
|
gx_canvas_pixelmap_draw(size->gx_rectangle_right - line_cover_gradient->gx_pixelmap_width + 1, size->gx_rectangle_top, line_cover_gradient);
|
|
} |