You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
240 lines
9.4 KiB
C++
240 lines
9.4 KiB
C++
#include <date/date.h>
|
|
#include <lvgl/lvgl.h>
|
|
#include "displayapp/screens/WatchFaceAksdark.h"
|
|
#include "displayapp/screens/BatteryIcon.h"
|
|
#include "displayapp/screens/NotificationIcon.h"
|
|
#include "displayapp/screens/Symbols.h"
|
|
#include "components/battery/BatteryController.h"
|
|
#include "components/ble/BleController.h"
|
|
#include "components/ble/NotificationManager.h"
|
|
#include "components/heartrate/HeartRateController.h"
|
|
#include "components/motion/MotionController.h"
|
|
#include "components/settings/Settings.h"
|
|
|
|
using namespace Pinetime::Applications::Screens;
|
|
|
|
|
|
|
|
WatchFaceAksdark::WatchFaceAksdark(DisplayApp* app,
|
|
Controllers::DateTime& dateTimeController,
|
|
Controllers::Battery& batteryController,
|
|
Controllers::Ble& bleController,
|
|
Controllers::NotificationManager& notificatioManager,
|
|
Controllers::Settings& settingsController,
|
|
Controllers::HeartRateController& heartRateController,
|
|
Controllers::MotionController& motionController)
|
|
: Screen(app),
|
|
currentDateTime {{}},
|
|
dateTimeController {dateTimeController},
|
|
batteryController {batteryController},
|
|
bleController {bleController},
|
|
notificatioManager {notificatioManager},
|
|
settingsController {settingsController},
|
|
heartRateController {heartRateController},
|
|
motionController {motionController} {
|
|
settingsController.SetClockFace(3);
|
|
|
|
//20 characters with default font size
|
|
//240x240 res
|
|
|
|
//BACKGROUND
|
|
background = lv_obj_create(lv_scr_act(), nullptr);
|
|
lv_obj_set_style_local_bg_color(background, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0x20, 0x20, 0x20));
|
|
lv_obj_set_style_local_radius(background, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 0);
|
|
lv_obj_set_size(background, 240, 240);
|
|
lv_obj_align(background, lv_scr_act(), LV_ALIGN_IN_TOP_LEFT, 0, 0);
|
|
|
|
/*
|
|
label_prompt_1 = lv_label_create(lv_scr_act(), nullptr);
|
|
lv_label_set_text_static(label_prompt_1, "X--------XX--------X");
|
|
SetupLabel(label_prompt_1, LV_ALIGN_IN_TOP_LEFT, 0, 0, &plex_mono_20);
|
|
|
|
label_prompt_2 = lv_label_create(lv_scr_act(), nullptr);
|
|
lv_label_set_text_static(label_prompt_2, "X--------XX--------X");
|
|
SetupLabel(label_prompt_2, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0, &plex_mono_20);
|
|
*/
|
|
|
|
//BATTERY
|
|
const int battery_x = 200;
|
|
const int battery_y = -100;
|
|
batteryValue = lv_label_create(lv_scr_act(), nullptr);
|
|
SetupLabel(batteryValue, battery_x, battery_y, &plex_mono_20);
|
|
chargeIcon = lv_label_create(lv_scr_act(), nullptr);
|
|
batteryIconParent = lv_label_create(lv_scr_act(), nullptr);
|
|
SetupBatteryIcon(batteryIconParent, battery_x-17, battery_y, 0x6ccc2d);
|
|
|
|
//TIME AND DATE
|
|
const int time_x = 20;
|
|
const int time_y = -40;
|
|
label_time = lv_label_create(lv_scr_act(), nullptr);
|
|
SetupLabel(label_time, time_x, time_y, &plex_mono_42);
|
|
label_date = lv_label_create(lv_scr_act(), nullptr);
|
|
SetupLabel(label_date, time_x + 40, time_y + 40, &plex_mono_20);
|
|
|
|
//STEP
|
|
const int step_x = 40;
|
|
const int step_y = 100;
|
|
stepValue = lv_label_create(lv_scr_act(), nullptr);
|
|
SetupLabel(stepValue, step_x, step_y, &plex_mono_20);
|
|
stepIcon = lv_label_create(lv_scr_act(), nullptr);
|
|
SetupIcon(stepIcon, step_x - 27, step_y, 0xffbf40, Symbols::shoe);
|
|
|
|
//HEARTBEAT
|
|
const int heartbeat_x = step_x + 160;
|
|
const int heartbeat_y = step_y;
|
|
heartbeatValue = lv_label_create(lv_scr_act(), nullptr);
|
|
SetupLabel(heartbeatValue, heartbeat_x, heartbeat_y, &plex_mono_20);
|
|
heartbeatIcon = lv_label_create(lv_scr_act(), nullptr);
|
|
SetupIcon(heartbeatIcon, heartbeat_x - 25, heartbeat_y, 0xFF716A, Symbols::heartBeat);
|
|
|
|
//NOTIF
|
|
notificationIcon = lv_label_create(lv_scr_act(), nullptr);
|
|
SetupIcon(notificationIcon, 110, 40, 0x21c7ca, NotificationIcon::GetIcon(true));
|
|
|
|
//BLUETOOTH
|
|
bluetoothIcon = lv_label_create(lv_scr_act(), nullptr);
|
|
SetupIcon(bluetoothIcon, 20, -100, 0x3b96ff, Symbols::bluetooth);
|
|
|
|
taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this);
|
|
Refresh();
|
|
}
|
|
|
|
WatchFaceAksdark::~WatchFaceAksdark() {
|
|
lv_task_del(taskRefresh);
|
|
lv_obj_clean(lv_scr_act());
|
|
}
|
|
|
|
void WatchFaceAksdark::Refresh() {
|
|
powerPresent = batteryController.IsPowerPresent();
|
|
batteryPercentRemaining = batteryController.PercentRemaining();
|
|
if (batteryPercentRemaining.IsUpdated() || powerPresent.IsUpdated()) {
|
|
lv_label_set_text_fmt(batteryValue, "#6ccc2d %d", batteryPercentRemaining.Get());
|
|
UpdateBattery();
|
|
}
|
|
|
|
isCharging = batteryController.IsCharging();
|
|
if (isCharging.IsUpdated()) {
|
|
if (isCharging.Get()) {
|
|
lv_obj_set_hidden(batteryIcon.GetObject(), true);
|
|
lv_obj_set_hidden(chargeIcon, false);
|
|
} else {
|
|
lv_obj_set_hidden(batteryIcon.GetObject(), false);
|
|
lv_obj_set_hidden(chargeIcon, true);
|
|
UpdateBattery();
|
|
}
|
|
}
|
|
|
|
bleState = bleController.IsConnected();
|
|
bleRadioEnabled = bleController.IsRadioEnabled();
|
|
if (bleState.IsUpdated() || bleRadioEnabled.IsUpdated()) {
|
|
if (!bleRadioEnabled.Get()) {
|
|
lv_obj_set_style_local_text_color(bluetoothIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0xfd2e59));
|
|
} else {
|
|
if (bleState.Get()) {
|
|
lv_obj_set_style_local_text_color(bluetoothIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x3b96ff));
|
|
} else {
|
|
lv_obj_set_style_local_text_color(bluetoothIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0xff1aba));
|
|
}
|
|
}
|
|
}
|
|
|
|
notificationState = notificatioManager.AreNewNotificationsAvailable();
|
|
if (notificationState.IsUpdated()) {
|
|
if (notificationState.Get())
|
|
{
|
|
lv_label_set_text_static(notificationIcon, Symbols::info);
|
|
lv_obj_set_style_local_text_color(notificationIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0xfd2e59));
|
|
|
|
}
|
|
else
|
|
{
|
|
lv_label_set_text_static(notificationIcon, Symbols::check);
|
|
lv_obj_set_style_local_text_color(notificationIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x21c7ca));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
currentDateTime = dateTimeController.CurrentDateTime();
|
|
|
|
if (currentDateTime.IsUpdated()) {
|
|
auto newDateTime = currentDateTime.Get();
|
|
|
|
auto dp = date::floor<date::days>(newDateTime);
|
|
auto time = date::make_time(newDateTime - dp);
|
|
auto yearMonthDay = date::year_month_day(dp);
|
|
|
|
auto year = static_cast<int>(yearMonthDay.year());
|
|
auto month = static_cast<Pinetime::Controllers::DateTime::Months>(static_cast<unsigned>(yearMonthDay.month()));
|
|
auto day = static_cast<unsigned>(yearMonthDay.day());
|
|
auto dayOfWeek = static_cast<Pinetime::Controllers::DateTime::Days>(date::weekday(yearMonthDay).iso_encoding());
|
|
|
|
uint8_t hour = time.hours().count();
|
|
uint8_t minute = time.minutes().count();
|
|
uint8_t second = time.seconds().count();
|
|
|
|
if (displayedHour != hour || displayedMinute != minute || displayedSecond != second) {
|
|
displayedHour = hour;
|
|
displayedMinute = minute;
|
|
displayedSecond = second;
|
|
lv_label_set_text_fmt(label_time, "#21c7ca %02d:%02d:%02d", hour, minute, second);
|
|
}
|
|
|
|
if ((year != currentYear) || (month != currentMonth) || (dayOfWeek != currentDayOfWeek) || (day != currentDay)) {
|
|
lv_label_set_text_fmt(label_date, "#8394ff %02d-%02d-%04d#", char(day), char(month), short(year));
|
|
|
|
currentYear = year;
|
|
currentMonth = month;
|
|
currentDayOfWeek = dayOfWeek;
|
|
currentDay = day;
|
|
}
|
|
}
|
|
|
|
heartbeat = heartRateController.HeartRate();
|
|
heartbeatRunning = heartRateController.State() != Controllers::HeartRateController::States::Stopped;
|
|
if (heartbeat.IsUpdated() || heartbeatRunning.IsUpdated()) {
|
|
if (heartbeatRunning.Get()) {
|
|
lv_label_set_text_fmt(heartbeatValue, "#FF716A %d#", heartbeat.Get());
|
|
lv_label_set_text_static(heartbeatIcon, Symbols::heartBeat);
|
|
} else {
|
|
lv_label_set_text_static(heartbeatValue, "#FF716A -#");
|
|
lv_label_set_text(heartbeatIcon, Symbols::heartBeat);
|
|
}
|
|
}
|
|
|
|
stepCount = motionController.NbSteps();
|
|
motionSensorOk = motionController.IsSensorOk();
|
|
if (stepCount.IsUpdated() || motionSensorOk.IsUpdated()) {
|
|
lv_label_set_text_fmt(stepValue, "#ffbf40 %lu#", stepCount.Get());
|
|
}
|
|
}
|
|
|
|
void WatchFaceAksdark::SetupLabel(lv_obj_t* label, int x_ofs, int y_ofs, _lv_font_struct* font)
|
|
{
|
|
lv_label_set_recolor(label, true);
|
|
lv_obj_align(label, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, x_ofs, y_ofs);
|
|
lv_obj_set_style_local_text_font(label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font);
|
|
}
|
|
|
|
void WatchFaceAksdark::SetupIcon(lv_obj_t* label, int x_ofs, int y_ofs, uint32_t hexColor, const char* icon)
|
|
{
|
|
lv_obj_align(label, nullptr, LV_ALIGN_IN_LEFT_MID, x_ofs, y_ofs);
|
|
lv_obj_set_style_local_text_color(label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(hexColor));
|
|
lv_label_set_text_static(label, icon);
|
|
}
|
|
|
|
void WatchFaceAksdark::SetupBatteryIcon(lv_obj_t* batteryIconParent, int x_ofs, int y_ofs, uint32_t hexColor)
|
|
{
|
|
lv_obj_align(batteryIconParent, nullptr, LV_ALIGN_IN_LEFT_MID, x_ofs, y_ofs);
|
|
lv_label_set_text_static(batteryIconParent, " ");
|
|
batteryIcon.Create(batteryIconParent);
|
|
batteryIcon.SetColor(lv_color_hex(hexColor));
|
|
lv_obj_align(batteryIcon.GetObject(), nullptr, LV_ALIGN_IN_LEFT_MID, 0, 0);
|
|
SetupIcon(chargeIcon, x_ofs, y_ofs, hexColor, Symbols::plug);
|
|
}
|
|
|
|
void WatchFaceAksdark::UpdateBattery()
|
|
{
|
|
auto batteryPercent = batteryPercentRemaining.Get();
|
|
batteryIcon.SetBatteryPercentage(batteryPercent);
|
|
} |