Skip to content

Commit 43d1126

Browse files
committed
Improved the Terminal Watchfaces UI
+ Reorder code to match the widgets order in the UI. + Moved all objects (rows) into a container + 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](InfiniTimeOrg#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 cd54f0f commit 43d1126

File tree

2 files changed

+78
-62
lines changed

2 files changed

+78
-62
lines changed

src/displayapp/screens/WatchFaceTerminal.cpp

Lines changed: 73 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
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

@@ -27,40 +27,43 @@ WatchFaceTerminal::WatchFaceTerminal(Controllers::DateTime& dateTimeController,
2727
settingsController {settingsController},
2828
heartRateController {heartRateController},
2929
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);
3730

38-
notificationIcon = lv_label_create(lv_scr_act(), nullptr);
39-
lv_obj_align(notificationIcon, nullptr, LV_ALIGN_IN_LEFT_MID, 0, -100);
31+
container = lv_cont_create(lv_scr_act(), nullptr);
32+
lv_cont_set_layout(container, LV_LAYOUT_COLUMN_LEFT);
33+
lv_cont_set_fit(container, LV_FIT_TIGHT);
34+
lv_obj_set_style_local_pad_inner(container, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, -3);
35+
lv_obj_set_style_local_bg_opa(container, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP);
4036

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);
37+
notificationIcon = lv_label_create(container, nullptr);
4438

45-
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);
39+
label_prompt_1 = lv_label_create(container, nullptr);
40+
lv_obj_set_style_local_text_color(label_prompt_1, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::lightGray);
4741
lv_label_set_text_static(label_prompt_1, "user@watch:~ $ now");
4842

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-
label_time = lv_label_create(lv_scr_act(), nullptr);
43+
label_time = lv_label_create(container, nullptr);
5444
lv_label_set_recolor(label_time, true);
55-
lv_obj_align(label_time, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, -60);
5645

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);
46+
label_date = lv_label_create(container, nullptr);
47+
lv_label_set_recolor(label_date, true);
6048

61-
stepValue = lv_label_create(lv_scr_act(), nullptr);
49+
batteryValue = lv_label_create(container, nullptr);
50+
lv_label_set_recolor(batteryValue, true);
51+
52+
stepValue = lv_label_create(container, 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+
56+
heartbeatValue = lv_label_create(container, nullptr);
57+
lv_label_set_recolor(heartbeatValue, true);
58+
59+
connectState = lv_label_create(container, nullptr);
60+
lv_label_set_recolor(connectState, true);
61+
62+
label_prompt_2 = lv_label_create(container, nullptr);
63+
lv_obj_set_style_local_text_color(label_prompt_2, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::lightGray);
64+
lv_label_set_text_static(label_prompt_2, "user@watch:~ $");
65+
66+
lv_obj_align(container, nullptr, LV_ALIGN_IN_TOP_LEFT, 0, 20);
6467

6568
taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this);
6669
Refresh();
@@ -72,33 +75,10 @@ WatchFaceTerminal::~WatchFaceTerminal() {
7275
}
7376

7477
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-
9878
notificationState = notificationManager.AreNewNotificationsAvailable();
9979
if (notificationState.IsUpdated()) {
10080
if (notificationState.Get()) {
101-
lv_label_set_text_static(notificationIcon, "You have mail.");
81+
lv_label_set_text_static(notificationIcon, "[1]+ Notify");
10282
} else {
10383
lv_label_set_text_static(notificationIcon, "");
10484
}
@@ -120,32 +100,67 @@ void WatchFaceTerminal::Refresh() {
120100
hour = hour - 12;
121101
ampmChar[0] = 'P';
122102
}
123-
lv_label_set_text_fmt(label_time, "[TIME]#11cc55 %02d:%02d:%02d %s#", hour, minute, second, ampmChar);
103+
lv_label_set_text_fmt(label_time, "#fffff [TIME]# #11cc55 %02d:%02d:%02d %s#", hour, minute, second, ampmChar);
124104
} else {
125-
lv_label_set_text_fmt(label_time, "[TIME]#11cc55 %02d:%02d:%02d", hour, minute, second);
105+
lv_label_set_text_fmt(label_time, "#ffffff [TIME]# #11cc55 %02d:%02d:%02d#", hour, minute, second);
126106
}
127107

128108
currentDate = std::chrono::time_point_cast<std::chrono::days>(currentDateTime.Get());
129109
if (currentDate.IsUpdated()) {
130110
uint16_t year = dateTimeController.Year();
131111
Controllers::DateTime::Months month = dateTimeController.Month();
132112
uint8_t day = dateTimeController.Day();
133-
lv_label_set_text_fmt(label_date, "[DATE]#007fff %04d-%02d-%02d#", short(year), char(month), char(day));
113+
lv_label_set_text_fmt(label_date, "#ffffff [DATE]# #007fff %04d-%02d-%02d#", short(year), char(month), char(day));
134114
}
135115
}
136116

117+
powerPresent = batteryController.IsPowerPresent();
118+
batteryPercentRemaining = batteryController.PercentRemaining();
119+
if (batteryPercentRemaining.IsUpdated() || powerPresent.IsUpdated()) {
120+
// HSV color model has red at 0° and green at 120°.
121+
// We lock satuation and brightness at 100% and traverse the cilinder
122+
// between red and green, thus avoiding the darker RGB on medium battery
123+
// charges and giving us a much nicer color range.
124+
uint8_t hue = batteryPercentRemaining.Get() * 120 / 100;
125+
lv_obj_set_style_local_text_color(batteryValue, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hsv_to_rgb(hue, 100, 100));
126+
lv_label_set_text_fmt(batteryValue, "#ffffff [BATT]# %d%%", batteryPercentRemaining.Get());
127+
if (batteryController.IsCharging()) {
128+
lv_label_ins_text(batteryValue, LV_LABEL_POS_LAST, " Charging");
129+
}
130+
}
131+
132+
stepCount = motionController.NbSteps();
133+
if (stepCount.IsUpdated()) {
134+
lv_label_set_text_fmt(stepValue, "#ffffff [STEP]# %lu steps", stepCount.Get());
135+
}
136+
137137
heartbeat = heartRateController.HeartRate();
138138
heartbeatRunning = heartRateController.State() != Controllers::HeartRateController::States::Stopped;
139139
if (heartbeat.IsUpdated() || heartbeatRunning.IsUpdated()) {
140140
if (heartbeatRunning.Get()) {
141-
lv_label_set_text_fmt(heartbeatValue, "[L_HR]#ee3311 %d bpm#", heartbeat.Get());
141+
142+
lv_obj_set_style_local_text_color(heartbeatValue, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::deepOrange);
143+
lv_label_set_text_fmt(heartbeatValue, "#ffffff [L_HR]# %d bpm", heartbeat.Get());
142144
} else {
143-
lv_label_set_text_static(heartbeatValue, "[L_HR]#ee3311 ---#");
145+
lv_label_set_text_static(heartbeatValue, "#ffffff [L_HR]# ---");
146+
lv_obj_set_style_local_text_color(heartbeatValue, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::gray);
144147
}
145148
}
146149

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

src/displayapp/screens/WatchFaceTerminal.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,16 @@ 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* container;
51+
lv_obj_t* notificationIcon;
52+
lv_obj_t* label_prompt_1;
5053
lv_obj_t* label_time;
5154
lv_obj_t* label_date;
52-
lv_obj_t* label_prompt_1;
53-
lv_obj_t* label_prompt_2;
5455
lv_obj_t* batteryValue;
55-
lv_obj_t* heartbeatValue;
5656
lv_obj_t* stepValue;
57-
lv_obj_t* notificationIcon;
57+
lv_obj_t* heartbeatValue;
5858
lv_obj_t* connectState;
59+
lv_obj_t* label_prompt_2;
5960

6061
Controllers::DateTime& dateTimeController;
6162
const Controllers::Battery& batteryController;

0 commit comments

Comments
 (0)