1+ #include " WatchFaceTerminal.h"
2+
3+ #include < date/date.h>
4+ #include < lvgl/lvgl.h>
5+ #include < cstdio>
6+ #include " BatteryIcon.h"
7+ #include " BleIcon.h"
8+ #include " NotificationIcon.h"
9+ #include " Symbols.h"
10+ #include " components/battery/BatteryController.h"
11+ #include " components/ble/BleController.h"
12+ #include " components/ble/NotificationManager.h"
13+ #include " components/heartrate/HeartRateController.h"
14+ #include " components/motion/MotionController.h"
15+ #include " components/settings/Settings.h"
16+ #include " ../DisplayApp.h"
17+
18+ using namespace Pinetime ::Applications::Screens;
19+
20+ WatchFaceTerminal::WatchFaceTerminal (DisplayApp* app,
21+ Controllers::DateTime& dateTimeController,
22+ Controllers::Battery& batteryController,
23+ Controllers::Ble& bleController,
24+ Controllers::NotificationManager& notificatioManager,
25+ Controllers::Settings& settingsController,
26+ Controllers::HeartRateController& heartRateController,
27+ Controllers::MotionController& motionController)
28+ : Screen(app),
29+ currentDateTime {{}},
30+ dateTimeController {dateTimeController},
31+ batteryController {batteryController},
32+ bleController {bleController},
33+ notificatioManager {notificatioManager},
34+ settingsController {settingsController},
35+ heartRateController {heartRateController},
36+ motionController {motionController} {
37+ settingsController.SetClockFace (0 );
38+
39+ displayedChar[0 ] = 0 ;
40+ displayedChar[1 ] = 0 ;
41+ displayedChar[2 ] = 0 ;
42+ displayedChar[3 ] = 0 ;
43+ displayedChar[4 ] = 0 ;
44+
45+ batteryIcon = lv_label_create (lv_scr_act (), nullptr );
46+ lv_label_set_text (batteryIcon, Symbols::batteryFull);
47+ lv_obj_align (batteryIcon, lv_scr_act (), LV_ALIGN_IN_BOTTOM_RIGHT, -5 , 2 );
48+
49+ batteryPlug = lv_label_create (lv_scr_act (), nullptr );
50+ lv_label_set_text (batteryPlug, Symbols::plug);
51+ lv_obj_align (batteryPlug, batteryIcon, LV_ALIGN_OUT_LEFT_MID, -5 , 0 );
52+
53+ batteryPercent = lv_label_create (lv_scr_act (), nullptr );
54+ lv_label_set_recolor (batteryPercent, true );
55+ lv_obj_align (batteryPercent, lv_scr_act (), LV_ALIGN_IN_LEFT_MID, 0 , -20 );
56+
57+ bleIcon = lv_label_create (lv_scr_act (), nullptr );
58+ lv_label_set_text (bleIcon, Symbols::bluetooth);
59+ lv_obj_align (bleIcon, batteryPlug, LV_ALIGN_OUT_LEFT_MID, -5 , 0 );
60+
61+ notificationIcon = lv_label_create (lv_scr_act (), NULL );
62+ lv_label_set_text (notificationIcon, NotificationIcon::GetIcon (false ));
63+ lv_obj_align (notificationIcon, nullptr , LV_ALIGN_IN_TOP_LEFT, 10 , 0 );
64+
65+ label_date = lv_label_create (lv_scr_act (), nullptr );
66+ lv_label_set_recolor (label_date, true );
67+ lv_obj_align (label_date, lv_scr_act (), LV_ALIGN_IN_LEFT_MID, 0 , -40 );
68+
69+ label_prompt_1 = lv_label_create (lv_scr_act (), nullptr );
70+ lv_obj_align (label_prompt_1, lv_scr_act (), LV_ALIGN_IN_LEFT_MID, 0 , -80 );
71+ lv_label_set_text (label_prompt_1, " user@watch:~ $ now" );
72+
73+ label_prompt_2 = lv_label_create (lv_scr_act (), nullptr );
74+ lv_obj_align (label_prompt_2, lv_scr_act (), LV_ALIGN_IN_LEFT_MID, 0 , 40 );
75+ lv_label_set_text (label_prompt_2, " user@watch:~ $" );
76+
77+ label_time = lv_label_create (lv_scr_act (), nullptr );
78+ lv_label_set_recolor (label_time, true );
79+ lv_obj_align (label_time, lv_scr_act (), LV_ALIGN_IN_LEFT_MID, 0 , -60 );
80+
81+ backgroundLabel = lv_label_create (lv_scr_act (), nullptr );
82+ lv_obj_set_click (backgroundLabel, true );
83+ lv_label_set_long_mode (backgroundLabel, LV_LABEL_LONG_CROP);
84+ lv_obj_set_size (backgroundLabel, 240 , 240 );
85+ lv_obj_set_pos (backgroundLabel, 0 , 0 );
86+ lv_label_set_text (backgroundLabel, " " );
87+
88+ heartbeatValue = lv_label_create (lv_scr_act (), nullptr );
89+ lv_label_set_recolor (heartbeatValue, true );
90+ lv_label_set_text (heartbeatValue, " [L_HR]#ee3311 0 bpm#" );
91+ lv_obj_align (heartbeatValue, lv_scr_act (), LV_ALIGN_IN_LEFT_MID, 0 , 20 );
92+
93+ stepValue = lv_label_create (lv_scr_act (), nullptr );
94+ lv_label_set_recolor (stepValue, true );
95+ lv_label_set_text (stepValue, " [STEP]#ee3377 0 steps#" );
96+ lv_obj_align (stepValue, lv_scr_act (), LV_ALIGN_IN_LEFT_MID, 0 , 0 );
97+ }
98+
99+ WatchFaceTerminal::~WatchFaceTerminal () {
100+ lv_obj_clean (lv_scr_act ());
101+ }
102+
103+ bool WatchFaceTerminal::Refresh () {
104+ batteryPercentRemaining = batteryController.PercentRemaining ();
105+ if (batteryPercentRemaining.IsUpdated ()) {
106+ auto batteryPercent = batteryPercentRemaining.Get ();
107+ lv_label_set_text (batteryIcon, BatteryIcon::GetBatteryIcon (batteryPercent));
108+ auto isCharging = batteryController.IsCharging () || batteryController.IsPowerPresent ();
109+ lv_label_set_text (batteryPlug, BatteryIcon::GetPlugIcon (isCharging));
110+ }
111+
112+ bleState = bleController.IsConnected ();
113+ if (bleState.IsUpdated ()) {
114+ if (bleState.Get () == true ) {
115+ lv_label_set_text (bleIcon, BleIcon::GetIcon (true ));
116+ } else {
117+ lv_label_set_text (bleIcon, BleIcon::GetIcon (false ));
118+ }
119+ }
120+ lv_obj_align (batteryIcon, lv_scr_act (), LV_ALIGN_IN_TOP_RIGHT, -5 , 5 );
121+ lv_obj_align (batteryPlug, batteryIcon, LV_ALIGN_OUT_LEFT_MID, -5 , 0 );
122+ lv_obj_align (bleIcon, batteryPlug, LV_ALIGN_OUT_LEFT_MID, -5 , 0 );
123+
124+ notificationState = notificatioManager.AreNewNotificationsAvailable ();
125+ if (notificationState.IsUpdated ()) {
126+ if (notificationState.Get () == true )
127+ lv_label_set_text (notificationIcon, NotificationIcon::GetIcon (true ));
128+ else
129+ lv_label_set_text (notificationIcon, NotificationIcon::GetIcon (false ));
130+ }
131+
132+ currentDateTime = dateTimeController.CurrentDateTime ();
133+
134+ if (currentDateTime.IsUpdated ()) {
135+ auto newDateTime = currentDateTime.Get ();
136+
137+ auto dp = date::floor<date::days>(newDateTime);
138+ auto time = date::make_time (newDateTime-dp);
139+ auto yearMonthDay = date::year_month_day (dp);
140+
141+ auto year = (int )yearMonthDay.year ();
142+ auto month = static_cast <Pinetime::Controllers::DateTime::Months>((unsigned )yearMonthDay.month ());
143+ auto day = (unsigned )yearMonthDay.day ();
144+ auto dayOfWeek = static_cast <Pinetime::Controllers::DateTime::Days>(date::weekday (yearMonthDay).iso_encoding ());
145+
146+ auto hour = time.hours ().count ();
147+ auto minute = time.minutes ().count ();
148+ auto second = time.seconds ().count ();
149+
150+ char minutesChar[6 ];
151+ sprintf (minutesChar, " %02d" , static_cast <int >(minute));
152+
153+ char hoursChar[8 ];
154+
155+ char ampmChar[3 ];
156+ if (settingsController.GetClockType () == Controllers::Settings::ClockType::H24) {
157+ sprintf (hoursChar, " %02d" , hour);
158+ } else {
159+ if (hour == 0 && hour != 12 ) {
160+ hour = 12 ;
161+ sprintf (ampmChar, " AM" );
162+ } else if (hour == 12 && hour != 0 ) {
163+ hour = 12 ;
164+ sprintf (ampmChar, " PM" );
165+ } else if (hour < 12 && hour != 0 ) {
166+ sprintf (ampmChar, " AM" );
167+ } else if (hour > 12 && hour != 0 ) {
168+ hour = hour - 12 ;
169+ sprintf (ampmChar, " PM" );
170+ }
171+ sprintf (hoursChar, " %02d" , hour);
172+ }
173+
174+ char secondsChar[5 ];
175+ sprintf (secondsChar, " %02d" , static_cast <int >(second));
176+
177+ auto batteryValue = static_cast <uint8_t >(batteryController.PercentRemaining ());
178+ /*
179+ char batteryGauge[12];
180+ if (batteryValue > 75){
181+ sprintf(batteryGauge, "[++++]"); //100-75
182+ }
183+ else if (batteryValue > 50){
184+ sprintf(batteryGauge, "[+++.]"); //75-50
185+ }
186+ else if (batteryValue > 25){
187+ sprintf(batteryGauge, "[++..]"); //50-25
188+ }
189+ else if (batteryValue > 10){
190+ sprintf(batteryGauge, "[+....]"); //25-10
191+ }
192+ else if (batteryValue > 0){
193+ sprintf(batteryGauge, "[!!!!!]"); //10-0
194+ }
195+ */
196+ char battStr[24 ];
197+ sprintf (battStr, " [BATT]#387b54 %d%\%#" , batteryValue);
198+ lv_label_set_text (batteryPercent, battStr);
199+
200+
201+ if (hoursChar[0 ] != displayedChar[0 ] || hoursChar[1 ] != displayedChar[1 ] || minutesChar[0 ] != displayedChar[2 ] || minutesChar[1 ] != displayedChar[3 ]) {
202+ displayedChar[0 ] = hoursChar[0 ];
203+ displayedChar[1 ] = hoursChar[1 ];
204+ displayedChar[2 ] = minutesChar[0 ];
205+ displayedChar[3 ] = minutesChar[1 ];
206+
207+ if (settingsController.GetClockType () == Controllers::Settings::ClockType::H12) {
208+ if (hoursChar[0 ] == ' 0' ) {
209+ hoursChar[0 ] = ' ' ;
210+ }
211+ }
212+
213+ char timeStr[42 ];
214+ sprintf (timeStr, " [TIME]#11cc55 %c%c:%c%c:%c%c %s#" , hoursChar[0 ],hoursChar[1 ],minutesChar[0 ], minutesChar[1 ], secondsChar[0 ], secondsChar[1 ], ampmChar);
215+
216+ lv_label_set_text (label_time, timeStr);
217+ }
218+
219+ if ((year != currentYear) || (month != currentMonth) || (dayOfWeek != currentDayOfWeek) || (day != currentDay)) {
220+
221+ char dateStr[38 ];
222+ sprintf (dateStr, " [DATE]#007fff %s %s %d#" , dateTimeController.DayOfWeekShortToString (), dateTimeController.MonthShortToString (), char (day));
223+ lv_label_set_text (label_date, dateStr);
224+
225+
226+ currentYear = year;
227+ currentMonth = month;
228+ currentDayOfWeek = dayOfWeek;
229+ currentDay = day;
230+ }
231+ }
232+
233+ heartbeat = heartRateController.HeartRate ();
234+ heartbeatRunning = heartRateController.State () != Controllers::HeartRateController::States::Stopped;
235+ if (heartbeat.IsUpdated () || heartbeatRunning.IsUpdated ()) {
236+ char heartbeatBuffer[28 ];
237+ if (heartbeatRunning.Get ())
238+ sprintf (heartbeatBuffer, " [L_HR]#ee3311 %d bpm#" , heartbeat.Get ());
239+ else
240+ sprintf (heartbeatBuffer, " [L_HR]#ee3311 ---#" );
241+
242+ lv_label_set_text (heartbeatValue, heartbeatBuffer);
243+ }
244+
245+ stepCount = motionController.NbSteps ();
246+ motionSensorOk = motionController.IsSensorOk ();
247+ char stepString[34 ];
248+ if (stepCount.IsUpdated () || motionSensorOk.IsUpdated ()) {
249+ sprintf (stepString, " [STEP]#ee3377 %lu steps#" , stepCount.Get ());
250+ lv_label_set_text (stepValue, stepString);
251+ }
252+ return running;
253+ }
0 commit comments