1+ #include " displayapp/screens/HeartRateZone.h"
2+ #include < lvgl/lvgl.h>
3+ #include < lvgl/lv_obj_style.h>
4+ #include < components/heartrate/HeartRateController.h>
5+
6+ #include " displayapp/DisplayApp.h"
7+ #include " displayapp/InfiniTimeTheme.h"
8+
9+ using namespace Pinetime ::Applications::Screens;
10+
11+ namespace {
12+ const char * ToString (Pinetime::Controllers::HeartRateController::States s) {
13+ switch (s) {
14+ case Pinetime::Controllers::HeartRateController::States::NotEnoughData:
15+ return " Not enough data,\n please wait..." ;
16+ case Pinetime::Controllers::HeartRateController::States::NoTouch:
17+ return " No touch detected" ;
18+ case Pinetime::Controllers::HeartRateController::States::Running:
19+ return " Measuring..." ;
20+ case Pinetime::Controllers::HeartRateController::States::Stopped:
21+ return " Stopped" ;
22+ }
23+ return " " ;
24+ }
25+
26+ void btnStartStopEventHandler (lv_obj_t * obj, lv_event_t event) {
27+ auto * screen = static_cast <HeartRate*>(obj->user_data );
28+ screen->OnStartStopEvent (event);
29+ }
30+ }
31+
32+ HeartRateZone::HeartRateZone (Controllers::HeartRateController& heartRateController, System::SystemTask& systemTask)
33+ : heartRateController {heartRateController}, wakeLock(systemTask) {
34+ bool isHrRunning = heartRateController.State () != Controllers::HeartRateController::States::Stopped;
35+
36+ auto activity = heartRateController.Activity ();
37+ uint32_t total = 0 ;
38+
39+ auto hundreths_of_hour = pdMS_TO_TICKS (10 *60 *60 );
40+
41+ lv_obj_t * screen = lv_scr_act ();
42+ for (uint8_t i = 0 ; i < zone_bar.size (); i++) {
43+ zone_bar[i] = lv_bar_create (screen, nullptr );
44+
45+ // lv_bar_set_orientation(zone_bar[i], LV_BAR_ORIENTATION_HORIZONTAL);
46+ total += activity.zoneTime [i];
47+ lv_obj_set_style_local_line_color (zone_bar[i], LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, Colors::bgAlt);
48+ lv_obj_set_size (zone_bar[i], 240 , 20 );
49+ lv_obj_align (zone_bar[i], nullptr , LV_ALIGN_IN_TOP_LEFT, 10 , 25 * i);
50+
51+ label_time[i] = lv_label_create (zone_bar[i]);
52+ lv_obj_align (zone_bar[i], nullptr , LV_ALIGN_CENTER, 0 , 0 );
53+ }
54+
55+ lv_label_set_text_static (label_time[0 ], " Warm Up" );
56+ lv_label_set_text_static (label_time[1 ], " Recovery" );
57+ lv_label_set_text_static (label_time[2 ], " Aerobic" );
58+ lv_label_set_text_static (label_time[3 ], " Threshold" );
59+ lv_label_set_text_static (label_time[4 ], " Anaerobic" );
60+
61+ lv_obj_set_style_local_line_color (zone_bar[0 ], LV_BAR_PART_INDIC, LV_STATE_DEFAULT, Colors::blue);
62+ lv_obj_set_style_local_line_color (zone_bar[1 ], LV_BAR_PART_INDIC, LV_STATE_DEFAULT, Colors::green);
63+ lv_obj_set_style_local_line_color (zone_bar[2 ], LV_BAR_PART_INDIC, LV_STATE_DEFAULT, Colors::orange);
64+ lv_obj_set_style_local_line_color (zone_bar[3 ], LV_BAR_PART_INDIC, LV_STATE_DEFAULT, Colors::deepOrange);
65+ lv_obj_set_style_local_line_color (zone_bar[4 ], LV_BAR_PART_INDIC, LV_STATE_DEFAULT, Colors::heartRed);
66+
67+ auto bar_limit = total / hundreths_of_hour;
68+
69+ for (uint8_t i = 0 ; i < zone_bar.size (); i++) {
70+ uint32_t percent = activity.zoneTime [i] / hundreths_of_hour;
71+ lv_bar_set_range (zone_bar[i], 0 , bar_limit);
72+ lv_bar_set_value (zone_bar[i], percent, LV_ANIM_OFF);
73+ }
74+
75+ taskRefresh = lv_task_create (RefreshTaskCallback, 5000 , LV_TASK_PRIO_MID, this );
76+ }
77+
78+ HeartRateZone::~HeartRateZone () {
79+ lv_task_del (taskRefresh);
80+ lv_obj_clean (lv_scr_act ());
81+ }
82+
83+ void HeartRateZone::Refresh () {
84+ auto activity = heartRateController.Activity ();
85+ uint32_t total = 0 ;
86+
87+ auto hundreths_of_hour = pdMS_TO_TICKS (10 * 60 * 60 );
88+
89+ for (uint8_t i = 0 ; i < zone_bar.size (); i++) {
90+ total += activity.zoneTime [i];
91+ }
92+
93+ auto bar_limit = total / hundreths_of_hour;
94+
95+ for (uint8_t i = 0 ; i < zone_bar.size (); i++) {
96+ uint32_t percent = activity.zoneTime [i] / hundreths_of_hour;
97+ lv_bar_set_range (zone_bar[i], 0 , bar_limit);
98+ lv_bar_set_value (zone_bar[i], percent, LV_ANIM_OFF);
99+ }
100+ }
0 commit comments