2
2
#include " displayapp/screens/WatchFaceTerminal.h"
3
3
#include " displayapp/screens/BatteryIcon.h"
4
4
#include " displayapp/screens/NotificationIcon.h"
5
- #include " displayapp/screens/Symbols.h"
6
5
#include " components/battery/BatteryController.h"
7
6
#include " components/ble/BleController.h"
8
7
#include " components/ble/NotificationManager.h"
8
+ #include " components/ble/SimpleWeatherService.h"
9
9
#include " components/heartrate/HeartRateController.h"
10
10
#include " components/motion/MotionController.h"
11
11
#include " components/settings/Settings.h"
12
+ #include " displayapp/screens/WeatherSymbols.h"
13
+ #include " displayapp/InfiniTimeTheme.h"
14
+
12
15
13
16
using namespace Pinetime ::Applications::Screens;
14
17
18
+ namespace {
19
+ lv_color_t temperatureColor (int16_t temperature) {
20
+ if (temperature <= 0 ) { // freezing
21
+ return Colors::blue;
22
+ } else if (temperature <= 400 ) { // ice
23
+ return LV_COLOR_CYAN;
24
+ } else if (temperature >= 2700 ) { // hot
25
+ return Colors::deepOrange;
26
+ }
27
+ return Colors::orange; // normal
28
+ }
29
+ }
30
+
15
31
WatchFaceTerminal::WatchFaceTerminal (Controllers::DateTime& dateTimeController,
16
32
const Controllers::Battery& batteryController,
17
33
const Controllers::Ble& bleController,
18
34
Controllers::NotificationManager& notificationManager,
19
35
Controllers::Settings& settingsController,
20
36
Controllers::HeartRateController& heartRateController,
21
- Controllers::MotionController& motionController)
37
+ Controllers::MotionController& motionController,
38
+ Controllers::SimpleWeatherService& weatherService)
22
39
: currentDateTime {{}},
23
40
dateTimeController {dateTimeController},
24
41
batteryController {batteryController},
25
42
bleController {bleController},
26
43
notificationManager {notificationManager},
27
44
settingsController {settingsController},
28
45
heartRateController {heartRateController},
29
- motionController {motionController} {
30
- batteryValue = lv_label_create (lv_scr_act (), nullptr );
31
- lv_label_set_recolor (batteryValue, true );
32
- lv_obj_align (batteryValue, lv_scr_act (), LV_ALIGN_IN_LEFT_MID, 0 , -20 );
33
-
34
- connectState = lv_label_create (lv_scr_act (), nullptr );
35
- lv_label_set_recolor (connectState, true );
36
- lv_obj_align (connectState, lv_scr_act (), LV_ALIGN_IN_LEFT_MID, 0 , 40 );
46
+ motionController {motionController},
47
+ weatherService {weatherService} {
37
48
38
49
notificationIcon = lv_label_create (lv_scr_act (), nullptr );
39
50
lv_obj_align (notificationIcon, nullptr , LV_ALIGN_IN_LEFT_MID, 0 , -100 );
40
51
41
- label_date = lv_label_create (lv_scr_act (), nullptr );
42
- lv_label_set_recolor (label_date, true );
43
- lv_obj_align (label_date, lv_scr_act (), LV_ALIGN_IN_LEFT_MID, 0 , -40 );
44
-
45
52
label_prompt_1 = lv_label_create (lv_scr_act (), nullptr );
46
53
lv_obj_align (label_prompt_1, lv_scr_act (), LV_ALIGN_IN_LEFT_MID, 0 , -80 );
47
54
lv_label_set_text_static (label_prompt_1, " user@watch:~ $ now" );
48
55
49
- label_prompt_2 = lv_label_create (lv_scr_act (), nullptr );
50
- lv_obj_align (label_prompt_2, lv_scr_act (), LV_ALIGN_IN_LEFT_MID, 0 , 60 );
51
- lv_label_set_text_static (label_prompt_2, " user@watch:~ $" );
52
-
53
56
label_time = lv_label_create (lv_scr_act (), nullptr );
54
- lv_label_set_recolor (label_time, true );
57
+ lv_obj_set_style_local_text_color (label_time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::blue );
55
58
lv_obj_align (label_time, lv_scr_act (), LV_ALIGN_IN_LEFT_MID, 0 , -60 );
56
59
57
- heartbeatValue = lv_label_create (lv_scr_act (), nullptr );
58
- lv_label_set_recolor (heartbeatValue, true );
59
- lv_obj_align (heartbeatValue, lv_scr_act (), LV_ALIGN_IN_LEFT_MID, 0 , 20 );
60
+ label_date = lv_label_create (lv_scr_act (), nullptr );
61
+ lv_obj_set_style_local_text_color (label_date, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::blue);
62
+ lv_obj_align (label_date, lv_scr_act (), LV_ALIGN_IN_LEFT_MID, 0 , -40 );
63
+
64
+ weather = lv_label_create (lv_scr_act (), nullptr );
65
+ lv_obj_align (weather, lv_scr_act (), LV_ALIGN_IN_LEFT_MID, 0 , -20 );
66
+
67
+ batteryValue = lv_label_create (lv_scr_act (), nullptr );
68
+ lv_obj_align (batteryValue, lv_scr_act (), LV_ALIGN_IN_LEFT_MID, 0 , 0 );
60
69
61
70
stepValue = lv_label_create (lv_scr_act (), nullptr );
62
- lv_label_set_recolor (stepValue, true );
63
- lv_obj_align (stepValue, lv_scr_act (), LV_ALIGN_IN_LEFT_MID, 0 , 0 );
71
+ lv_obj_set_style_local_text_color (stepValue, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::orange);
72
+ lv_obj_align (stepValue, lv_scr_act (), LV_ALIGN_IN_LEFT_MID, 0 , 20 );
73
+
74
+ heartbeatValue = lv_label_create (lv_scr_act (), nullptr );
75
+ lv_obj_align (heartbeatValue, lv_scr_act (), LV_ALIGN_IN_LEFT_MID, 0 , 40 );
76
+
77
+ connectState = lv_label_create (lv_scr_act (), nullptr );
78
+ lv_obj_align (connectState, lv_scr_act (), LV_ALIGN_IN_LEFT_MID, 0 , 60 );
79
+
80
+ label_prompt_2 = lv_label_create (lv_scr_act (), nullptr );
81
+ lv_obj_align (label_prompt_2, lv_scr_act (), LV_ALIGN_IN_LEFT_MID, 0 , 80 );
82
+ lv_label_set_text_static (label_prompt_2, " user@watch:~ $" );
64
83
65
84
taskRefresh = lv_task_create (RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this );
66
85
Refresh ();
@@ -72,29 +91,6 @@ WatchFaceTerminal::~WatchFaceTerminal() {
72
91
}
73
92
74
93
void WatchFaceTerminal::Refresh () {
75
- powerPresent = batteryController.IsPowerPresent ();
76
- batteryPercentRemaining = batteryController.PercentRemaining ();
77
- if (batteryPercentRemaining.IsUpdated () || powerPresent.IsUpdated ()) {
78
- lv_label_set_text_fmt (batteryValue, " [BATT]#387b54 %d%%" , batteryPercentRemaining.Get ());
79
- if (batteryController.IsPowerPresent ()) {
80
- lv_label_ins_text (batteryValue, LV_LABEL_POS_LAST, " Charging" );
81
- }
82
- }
83
-
84
- bleState = bleController.IsConnected ();
85
- bleRadioEnabled = bleController.IsRadioEnabled ();
86
- if (bleState.IsUpdated () || bleRadioEnabled.IsUpdated ()) {
87
- if (!bleRadioEnabled.Get ()) {
88
- lv_label_set_text_static (connectState, " [STAT]#0082fc Disabled#" );
89
- } else {
90
- if (bleState.Get ()) {
91
- lv_label_set_text_static (connectState, " [STAT]#0082fc Connected#" );
92
- } else {
93
- lv_label_set_text_static (connectState, " [STAT]#0082fc Disconnected#" );
94
- }
95
- }
96
- }
97
-
98
94
notificationState = notificationManager.AreNewNotificationsAvailable ();
99
95
if (notificationState.IsUpdated ()) {
100
96
if (notificationState.Get ()) {
@@ -104,6 +100,7 @@ void WatchFaceTerminal::Refresh() {
104
100
}
105
101
}
106
102
103
+
107
104
currentDateTime = std::chrono::time_point_cast<std::chrono::seconds>(dateTimeController.CurrentDateTime ());
108
105
if (currentDateTime.IsUpdated ()) {
109
106
uint8_t hour = dateTimeController.Hours ();
@@ -120,32 +117,90 @@ void WatchFaceTerminal::Refresh() {
120
117
hour = hour - 12 ;
121
118
ampmChar[0 ] = ' P' ;
122
119
}
123
- lv_label_set_text_fmt (label_time, " [TIME]#11cc55 %02d:%02d:%02d %s#" , hour, minute, second, ampmChar);
120
+ lv_label_set_text_fmt (label_time, " [TIME] %02d:%02d:%02d %s#" , hour, minute, second, ampmChar);
124
121
} else {
125
- lv_label_set_text_fmt (label_time, " [TIME]#11cc55 %02d:%02d:%02d" , hour, minute, second);
122
+ lv_label_set_text_fmt (label_time, " [TIME] %02d:%02d:%02d" , hour, minute, second);
126
123
}
127
124
128
125
currentDate = std::chrono::time_point_cast<days>(currentDateTime.Get ());
129
126
if (currentDate.IsUpdated ()) {
130
127
uint16_t year = dateTimeController.Year ();
131
128
Controllers::DateTime::Months month = dateTimeController.Month ();
132
129
uint8_t day = dateTimeController.Day ();
133
- lv_label_set_text_fmt (label_date, " [DATE]#007fff %04d-%02d-%02d#" , short (year), char (month), char (day));
130
+ lv_label_set_text_fmt (label_date, " [DATE] %04d-%02d-%02d#" , short (year), char (month), char (day));
131
+ }
132
+ }
133
+
134
+
135
+ currentWeather = weatherService.Current ();
136
+ if (currentWeather.IsUpdated ()) {
137
+ auto optCurrentWeather = currentWeather.Get ();
138
+ if (optCurrentWeather) {
139
+ int16_t temp = optCurrentWeather->temperature ;
140
+ char tempUnit = ' C' ;
141
+ lv_obj_set_style_local_text_color (weather, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, temperatureColor (temp));
142
+ if (settingsController.GetWeatherFormat () == Controllers::Settings::WeatherFormat::Imperial) {
143
+ condition = Symbols::GetSimpleCondition (optCurrentWeather->iconId );
144
+ temp = Controllers::SimpleWeatherService::CelsiusToFahrenheit (temp);
145
+ tempUnit = ' F' ;
146
+ }
147
+ lv_label_set_text_fmt (weather, " [WTHR] %i°%c %s " , temp/100 , tempUnit, condition);
148
+ } else {
149
+ lv_label_set_text (weather, " [WTHR] ---°" );
150
+ lv_obj_set_style_local_text_color (weather, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::gray);
134
151
}
135
152
}
136
153
154
+
155
+ powerPresent = batteryController.IsPowerPresent ();
156
+ batteryPercentRemaining = batteryController.PercentRemaining ();
157
+ if (batteryPercentRemaining.IsUpdated () || powerPresent.IsUpdated ()) {
158
+ // HSV color model has red at 0° and green at 120°.
159
+ // We lock satuation and brightness at 100% and traverse the cilinder
160
+ // between red and green, thus avoiding the darker RGB on medium battery
161
+ // charges and giving us a much nicer color range.
162
+ uint8_t hue = batteryPercentRemaining.Get () * 120 / 100 ;
163
+ lv_obj_set_style_local_text_color (batteryValue, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hsv_to_rgb (hue, 100 , 100 ));
164
+ lv_label_set_text_fmt (batteryValue, " [BATT] %d%%" , batteryPercentRemaining.Get ());
165
+ if (batteryController.IsPowerPresent ()) {
166
+ lv_label_ins_text (batteryValue, LV_LABEL_POS_LAST, " Charging" );
167
+ }
168
+ }
169
+
170
+
171
+ stepCount = motionController.NbSteps ();
172
+ if (stepCount.IsUpdated ()) {
173
+ lv_label_set_text_fmt (stepValue, " [STEP] %lu steps#" , stepCount.Get ());
174
+ }
175
+
176
+
137
177
heartbeat = heartRateController.HeartRate ();
138
178
heartbeatRunning = heartRateController.State () != Controllers::HeartRateController::States::Stopped;
139
179
if (heartbeat.IsUpdated () || heartbeatRunning.IsUpdated ()) {
140
180
if (heartbeatRunning.Get ()) {
141
- lv_label_set_text_fmt (heartbeatValue, " [L_HR]#ee3311 %d bpm#" , heartbeat.Get ());
181
+
182
+ lv_obj_set_style_local_text_color (heartbeatValue, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::deepOrange);
183
+ lv_label_set_text_fmt (heartbeatValue, " [L_HR] %d bpm#" , heartbeat.Get ());
142
184
} else {
143
- lv_label_set_text_static (heartbeatValue, " [L_HR]#ee3311 ---#" );
185
+ lv_label_set_text_static (heartbeatValue, " [L_HR] ---#" );
186
+ lv_obj_set_style_local_text_color (heartbeatValue, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::gray);
144
187
}
145
188
}
146
189
147
- stepCount = motionController.NbSteps ();
148
- if (stepCount.IsUpdated ()) {
149
- lv_label_set_text_fmt (stepValue, " [STEP]#ee3377 %lu steps#" , stepCount.Get ());
190
+ bleState = bleController.IsConnected ();
191
+ bleRadioEnabled = bleController.IsRadioEnabled ();
192
+ if (bleState.IsUpdated () || bleRadioEnabled.IsUpdated ()) {
193
+ if (!bleRadioEnabled.Get ()) {
194
+ lv_label_set_text_static (connectState, " [STAT] Disabled#" );
195
+ lv_obj_set_style_local_text_color (connectState, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::gray);
196
+ } else {
197
+ if (bleState.Get ()) {
198
+ lv_label_set_text_static (connectState, " [STAT] Connected#" );
199
+ lv_obj_set_style_local_text_color (connectState, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::blue);
200
+ } else {
201
+ lv_label_set_text_static (connectState, " [STAT] Disconnected#" );
202
+ lv_obj_set_style_local_text_color (connectState, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::gray);
203
+ }
204
+ }
150
205
}
151
206
}
0 commit comments