Skip to content

Commit c312a6c

Browse files
committed
Improved the Terminal Watchfaces UI
+ Reorder code to match the widgets order in the UI. + Use InfintimeTheme Colors instead of hardcoded hex values + Added a new InfinitimeTheme color: gray, using it to turn certain values gray when they contain no data + Implement @vkareh's [variable battery icon](#1964) color to the battery percentage text. + Replaced the 'You have mail.' notification message with the message '[1]+ Notify' to better fit the terminal lore.
1 parent a2356f2 commit c312a6c

File tree

3 files changed

+77
-59
lines changed

3 files changed

+77
-59
lines changed

src/displayapp/InfiniTimeTheme.h

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ namespace Colors {
88
static constexpr lv_color_t green = LV_COLOR_MAKE(0x0, 0xb0, 0x0);
99
static constexpr lv_color_t blue = LV_COLOR_MAKE(0x0, 0x50, 0xff);
1010
static constexpr lv_color_t lightGray = LV_COLOR_MAKE(0xb0, 0xb0, 0xb0);
11+
static constexpr lv_color_t gray = LV_COLOR_MAKE(0x50, 0x50, 0x50);
1112

1213
static constexpr lv_color_t bg = LV_COLOR_MAKE(0x5d, 0x69, 0x7e);
1314
static constexpr lv_color_t bgAlt = LV_COLOR_MAKE(0x38, 0x38, 0x38);

src/displayapp/screens/WatchFaceTerminal.cpp

+72-55
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,17 @@
22
#include "displayapp/screens/WatchFaceTerminal.h"
33
#include "displayapp/screens/BatteryIcon.h"
44
#include "displayapp/screens/NotificationIcon.h"
5-
#include "displayapp/screens/Symbols.h"
65
#include "components/battery/BatteryController.h"
76
#include "components/ble/BleController.h"
87
#include "components/ble/NotificationManager.h"
98
#include "components/heartrate/HeartRateController.h"
109
#include "components/motion/MotionController.h"
1110
#include "components/settings/Settings.h"
11+
#include "displayapp/InfiniTimeTheme.h"
1212

1313
using namespace Pinetime::Applications::Screens;
1414

15+
1516
WatchFaceTerminal::WatchFaceTerminal(Controllers::DateTime& dateTimeController,
1617
const Controllers::Battery& batteryController,
1718
const Controllers::Ble& bleController,
@@ -27,40 +28,44 @@ WatchFaceTerminal::WatchFaceTerminal(Controllers::DateTime& dateTimeController,
2728
settingsController {settingsController},
2829
heartRateController {heartRateController},
2930
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);
3731

3832
notificationIcon = lv_label_create(lv_scr_act(), nullptr);
39-
lv_obj_align(notificationIcon, nullptr, LV_ALIGN_IN_LEFT_MID, 0, -100);
40-
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);
33+
lv_obj_align(notificationIcon, nullptr, LV_ALIGN_IN_LEFT_MID, 0, -90);
4434

4535
label_prompt_1 = lv_label_create(lv_scr_act(), nullptr);
46-
lv_obj_align(label_prompt_1, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, -80);
36+
lv_obj_set_style_local_text_color(label_prompt_1, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::lightGray);
37+
lv_obj_align(label_prompt_1, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, -70);
4738
lv_label_set_text_static(label_prompt_1, "user@watch:~ $ now");
4839

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-
5340
label_time = lv_label_create(lv_scr_act(), nullptr);
5441
lv_label_set_recolor(label_time, true);
55-
lv_obj_align(label_time, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, -60);
42+
lv_obj_align(label_time, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, -50);
5643

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);
44+
label_date = lv_label_create(lv_scr_act(), nullptr);
45+
lv_label_set_recolor(label_date, true);
46+
lv_obj_align(label_date, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, -30);
47+
48+
batteryValue = lv_label_create(lv_scr_act(), nullptr);
49+
lv_label_set_recolor(batteryValue, true);
50+
lv_obj_align(batteryValue, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, -10);
6051

6152
stepValue = lv_label_create(lv_scr_act(), nullptr);
6253
lv_label_set_recolor(stepValue, true);
63-
lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, 0);
54+
lv_obj_set_style_local_text_color(stepValue, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::orange);
55+
lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, 10);
56+
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, 30);
60+
61+
connectState = lv_label_create(lv_scr_act(), nullptr);
62+
lv_label_set_recolor(connectState, true);
63+
lv_obj_align(connectState, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, 50);
64+
65+
label_prompt_2 = lv_label_create(lv_scr_act(), nullptr);
66+
lv_obj_set_style_local_text_color(label_prompt_2, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::lightGray);
67+
lv_obj_align(label_prompt_2, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, 70);
68+
lv_label_set_text_static(label_prompt_2, "user@watch:~ $");
6469

6570
taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this);
6671
Refresh();
@@ -72,33 +77,10 @@ WatchFaceTerminal::~WatchFaceTerminal() {
7277
}
7378

7479
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-
9880
notificationState = notificationManager.AreNewNotificationsAvailable();
9981
if (notificationState.IsUpdated()) {
10082
if (notificationState.Get()) {
101-
lv_label_set_text_static(notificationIcon, "You have mail.");
83+
lv_label_set_text_static(notificationIcon, "[1]+ Notify");
10284
} else {
10385
lv_label_set_text_static(notificationIcon, "");
10486
}
@@ -120,32 +102,67 @@ void WatchFaceTerminal::Refresh() {
120102
hour = hour - 12;
121103
ampmChar[0] = 'P';
122104
}
123-
lv_label_set_text_fmt(label_time, "[TIME]#11cc55 %02d:%02d:%02d %s#", hour, minute, second, ampmChar);
105+
lv_label_set_text_fmt(label_time, "#fffff [TIME]# #11cc55 %02d:%02d:%02d %s#", hour, minute, second, ampmChar);
124106
} else {
125-
lv_label_set_text_fmt(label_time, "[TIME]#11cc55 %02d:%02d:%02d", hour, minute, second);
107+
lv_label_set_text_fmt(label_time, "#ffffff [TIME]# #11cc55 %02d:%02d:%02d#", hour, minute, second);
126108
}
127109

128110
currentDate = std::chrono::time_point_cast<std::chrono::days>(currentDateTime.Get());
129111
if (currentDate.IsUpdated()) {
130112
uint16_t year = dateTimeController.Year();
131113
Controllers::DateTime::Months month = dateTimeController.Month();
132114
uint8_t day = dateTimeController.Day();
133-
lv_label_set_text_fmt(label_date, "[DATE]#007fff %04d-%02d-%02d#", short(year), char(month), char(day));
115+
lv_label_set_text_fmt(label_date, "#ffffff [DATE]# #007fff %04d-%02d-%02d#", short(year), char(month), char(day));
116+
}
117+
}
118+
119+
powerPresent = batteryController.IsPowerPresent();
120+
batteryPercentRemaining = batteryController.PercentRemaining();
121+
if (batteryPercentRemaining.IsUpdated() || powerPresent.IsUpdated()) {
122+
// HSV color model has red at 0° and green at 120°.
123+
// We lock satuation and brightness at 100% and traverse the cilinder
124+
// between red and green, thus avoiding the darker RGB on medium battery
125+
// charges and giving us a much nicer color range.
126+
uint8_t hue = batteryPercentRemaining.Get() * 120 / 100;
127+
lv_obj_set_style_local_text_color(batteryValue, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hsv_to_rgb(hue, 100, 100));
128+
lv_label_set_text_fmt(batteryValue, "#ffffff [BATT]# %d%%", batteryPercentRemaining.Get());
129+
if (batteryController.IsCharging()) {
130+
lv_label_ins_text(batteryValue, LV_LABEL_POS_LAST, " Charging");
134131
}
135132
}
136133

134+
stepCount = motionController.NbSteps();
135+
if (stepCount.IsUpdated()) {
136+
lv_label_set_text_fmt(stepValue, "#ffffff [STEP]# %lu steps", stepCount.Get());
137+
}
138+
137139
heartbeat = heartRateController.HeartRate();
138140
heartbeatRunning = heartRateController.State() != Controllers::HeartRateController::States::Stopped;
139141
if (heartbeat.IsUpdated() || heartbeatRunning.IsUpdated()) {
140142
if (heartbeatRunning.Get()) {
141-
lv_label_set_text_fmt(heartbeatValue, "[L_HR]#ee3311 %d bpm#", heartbeat.Get());
143+
144+
lv_obj_set_style_local_text_color(heartbeatValue, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::deepOrange);
145+
lv_label_set_text_fmt(heartbeatValue, "#ffffff [L_HR]# %d bpm", heartbeat.Get());
142146
} else {
143-
lv_label_set_text_static(heartbeatValue, "[L_HR]#ee3311 ---#");
147+
lv_label_set_text_static(heartbeatValue, "#ffffff [L_HR]# ---");
148+
lv_obj_set_style_local_text_color(heartbeatValue, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::gray);
144149
}
145150
}
146151

147-
stepCount = motionController.NbSteps();
148-
if (stepCount.IsUpdated()) {
149-
lv_label_set_text_fmt(stepValue, "[STEP]#ee3377 %lu steps#", stepCount.Get());
152+
bleState = bleController.IsConnected();
153+
bleRadioEnabled = bleController.IsRadioEnabled();
154+
if (bleState.IsUpdated() || bleRadioEnabled.IsUpdated()) {
155+
if (!bleRadioEnabled.Get()) {
156+
lv_label_set_text_static(connectState, "#ffffff [STAT]# Disabled");
157+
lv_obj_set_style_local_text_color(connectState, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::gray);
158+
} else {
159+
if (bleState.Get()) {
160+
lv_label_set_text_static(connectState, "#ffffff [STAT]# Connected");
161+
lv_obj_set_style_local_text_color(connectState, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::blue);
162+
} else {
163+
lv_label_set_text_static(connectState, "#ffffff [STAT]# Disconnected");
164+
lv_obj_set_style_local_text_color(connectState, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::gray);
165+
}
166+
}
150167
}
151168
}

src/displayapp/screens/WatchFaceTerminal.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,15 @@ namespace Pinetime {
4747
Utility::DirtyValue<bool> notificationState {};
4848
Utility::DirtyValue<std::chrono::time_point<std::chrono::system_clock, std::chrono::days>> currentDate;
4949

50+
lv_obj_t* notificationIcon;
51+
lv_obj_t* label_prompt_1;
5052
lv_obj_t* label_time;
5153
lv_obj_t* label_date;
52-
lv_obj_t* label_prompt_1;
53-
lv_obj_t* label_prompt_2;
5454
lv_obj_t* batteryValue;
55-
lv_obj_t* heartbeatValue;
5655
lv_obj_t* stepValue;
57-
lv_obj_t* notificationIcon;
56+
lv_obj_t* heartbeatValue;
5857
lv_obj_t* connectState;
58+
lv_obj_t* label_prompt_2;
5959

6060
Controllers::DateTime& dateTimeController;
6161
const Controllers::Battery& batteryController;

0 commit comments

Comments
 (0)