Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trans watchface #2201

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,7 @@ list(APPEND SOURCE_FILES
displayapp/screens/WatchFaceTerminal.cpp
displayapp/screens/WatchFacePineTimeStyle.cpp
displayapp/screens/WatchFaceCasioStyleG7710.cpp
displayapp/screens/WatchFaceTrans.cpp

##

Expand Down
10 changes: 10 additions & 0 deletions src/components/datetime/DateTimeController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ using namespace Pinetime::Controllers;
namespace {
constexpr const char* const DaysStringShort[] = {"--", "MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"};
constexpr const char* const DaysStringShortLow[] = {"--", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
constexpr const char* const DaysString[] = {"--", "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY", "SUNDAY"};
constexpr const char* const DaysStringLow[] = {"--", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};
constexpr const char* const MonthsString[] = {"--", "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"};
constexpr const char* const MonthsStringLow[] =
{"--", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
Expand Down Expand Up @@ -144,6 +146,10 @@ const char* DateTime::DayOfWeekShortToString() const {
return DaysStringShort[static_cast<uint8_t>(DayOfWeek())];
}

const char* DateTime::DayOfWeekToString() const {
return DaysString[static_cast<uint8_t>(DayOfWeek())];
}

const char* DateTime::MonthShortToStringLow(Months month) {
return MonthsStringLow[static_cast<uint8_t>(month)];
}
Expand All @@ -152,6 +158,10 @@ const char* DateTime::DayOfWeekShortToStringLow(Days day) {
return DaysStringShortLow[static_cast<uint8_t>(day)];
}

const char* DateTime::DayOfWeekToStringLow(Days day) {
return DaysStringLow[static_cast<uint8_t>(day)];
}

void DateTime::Register(Pinetime::System::SystemTask* systemTask) {
this->systemTask = systemTask;
}
Expand Down
2 changes: 2 additions & 0 deletions src/components/datetime/DateTimeController.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,10 @@ namespace Pinetime {

const char* MonthShortToString() const;
const char* DayOfWeekShortToString() const;
const char* DayOfWeekToString() const;
static const char* MonthShortToStringLow(Months month);
static const char* DayOfWeekShortToStringLow(Days day);
static const char* DayOfWeekToStringLow(Days day);

std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> CurrentDateTime();

Expand Down
1 change: 1 addition & 0 deletions src/displayapp/UserApps.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "displayapp/screens/WatchFaceInfineat.h"
#include "displayapp/screens/WatchFacePineTimeStyle.h"
#include "displayapp/screens/WatchFaceTerminal.h"
#include "displayapp/screens/WatchFaceTrans.h"

namespace Pinetime {
namespace Applications {
Expand Down
1 change: 1 addition & 0 deletions src/displayapp/apps/Apps.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ namespace Pinetime {
Terminal,
Infineat,
CasioStyleG7710,
Trans,
};

template <Apps>
Expand Down
1 change: 1 addition & 0 deletions src/displayapp/apps/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ else()
set(DEFAULT_WATCHFACE_TYPES "${DEFAULT_WATCHFACE_TYPES}, WatchFace::Terminal")
set(DEFAULT_WATCHFACE_TYPES "${DEFAULT_WATCHFACE_TYPES}, WatchFace::Infineat")
set(DEFAULT_WATCHFACE_TYPES "${DEFAULT_WATCHFACE_TYPES}, WatchFace::CasioStyleG7710")
set(DEFAULT_WATCHFACE_TYPES "${DEFAULT_WATCHFACE_TYPES}, WatchFace::Trans")
set(WATCHFACE_TYPES "${DEFAULT_WATCHFACE_TYPES}" CACHE STRING "List of watch faces to build into the firmware")
endif()

Expand Down
167 changes: 167 additions & 0 deletions src/displayapp/screens/WatchFaceTrans.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
#include <lvgl/lvgl.h>
#include "displayapp/screens/WatchFaceTrans.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/motion/MotionController.h"
#include "components/settings/Settings.h"

using namespace Pinetime::Applications::Screens;

WatchFaceTrans::WatchFaceTrans(Controllers::DateTime& dateTimeController,
const Controllers::Battery& batteryController,
const Controllers::Ble& bleController,
Controllers::NotificationManager& notificationManager,
Controllers::Settings& settingsController,
Controllers::MotionController& motionController)
: currentDateTime {{}},
dateTimeController {dateTimeController},
batteryController {batteryController},
bleController {bleController},
notificationManager {notificationManager},
settingsController {settingsController},
motionController {motionController} {

topBlueBackground = lv_obj_create(lv_scr_act(), nullptr);
lv_obj_set_size(topBlueBackground, LV_HOR_RES, LV_VER_RES / 5);
lv_obj_set_pos(topBlueBackground, 0, 0);
lv_obj_set_style_local_bg_color(topBlueBackground, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, lightBlue);
lv_obj_set_style_local_radius(topBlueBackground, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, 0);
topPinkBackground = lv_obj_create(lv_scr_act(), nullptr);
lv_obj_set_size(topPinkBackground, LV_HOR_RES, LV_VER_RES / 5);
lv_obj_set_pos(topPinkBackground, 0, LV_VER_RES / 5);
lv_obj_set_style_local_bg_color(topPinkBackground, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, lightPink);
lv_obj_set_style_local_radius(topPinkBackground, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, 0);
whiteBackground = lv_obj_create(lv_scr_act(), nullptr);
lv_obj_set_size(whiteBackground, LV_HOR_RES, LV_VER_RES / 5);
lv_obj_set_pos(whiteBackground, 0, 2 * LV_VER_RES / 5);
lv_obj_set_style_local_bg_color(whiteBackground, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE);
lv_obj_set_style_local_radius(whiteBackground, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, 0);
bottomPinkBackground = lv_obj_create(lv_scr_act(), nullptr);
lv_obj_set_size(bottomPinkBackground, LV_HOR_RES, LV_VER_RES / 5);
lv_obj_set_pos(bottomPinkBackground, 0, 3 * LV_VER_RES / 5);
lv_obj_set_style_local_bg_color(bottomPinkBackground, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, lightPink);
lv_obj_set_style_local_radius(bottomPinkBackground, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, 0);
bottomBlueBackground = lv_obj_create(lv_scr_act(), nullptr);
lv_obj_set_size(bottomBlueBackground, LV_HOR_RES, LV_VER_RES / 5);
lv_obj_set_pos(bottomBlueBackground, 0, 4 * LV_VER_RES / 5);
lv_obj_set_style_local_bg_color(bottomBlueBackground, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, lightBlue);
lv_obj_set_style_local_radius(bottomBlueBackground, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, 0);

bluetoothStatus = lv_label_create(lv_scr_act(), nullptr);
lv_label_set_text_static(bluetoothStatus, "");
lv_obj_align(bluetoothStatus, nullptr, LV_ALIGN_IN_TOP_RIGHT, -16, 0);

batteryValue = lv_label_create(lv_scr_act(), nullptr);
lv_label_set_recolor(batteryValue, true);
lv_obj_align(batteryValue, lv_scr_act(), LV_ALIGN_CENTER, 0, -96);
lv_label_set_align(batteryValue, LV_LABEL_ALIGN_CENTER);
lv_obj_set_auto_realign(batteryValue, true);

notificationIcon = lv_label_create(lv_scr_act(), nullptr);
lv_obj_align(notificationIcon, nullptr, LV_ALIGN_IN_LEFT_MID, 0, -110);
lv_obj_set_style_local_text_color(notificationIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK);

labelDate = lv_label_create(lv_scr_act(), nullptr);
lv_label_set_recolor(labelDate, true);
lv_obj_align(labelDate, lv_scr_act(), LV_ALIGN_CENTER, 0, -48);
lv_label_set_align(labelDate, LV_LABEL_ALIGN_CENTER);
lv_obj_set_auto_realign(labelDate, true);

labelTime = lv_label_create(lv_scr_act(), nullptr);
lv_label_set_recolor(labelTime, true);
lv_obj_align(labelTime, lv_scr_act(), LV_ALIGN_CENTER, 0, 0);
lv_label_set_align(labelTime, LV_LABEL_ALIGN_CENTER);
lv_obj_set_style_local_text_font(labelTime, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_42);
lv_obj_set_auto_realign(labelTime, true);

labelDay = lv_label_create(lv_scr_act(), nullptr);
lv_label_set_recolor(labelDay, true);
lv_obj_align(labelDay, lv_scr_act(), LV_ALIGN_CENTER, 0, 48);
lv_label_set_align(labelDay, LV_LABEL_ALIGN_CENTER);
lv_obj_set_auto_realign(labelDay, true);

stepValue = lv_label_create(lv_scr_act(), nullptr);
lv_label_set_recolor(stepValue, true);
lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_CENTER, 0, 96);
lv_label_set_align(stepValue, LV_LABEL_ALIGN_CENTER);
lv_obj_set_auto_realign(stepValue, true);

taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this);
Refresh();
}

WatchFaceTrans::~WatchFaceTrans() {
lv_task_del(taskRefresh);
lv_obj_clean(lv_scr_act());
}

void WatchFaceTrans::Refresh() {
powerPresent = batteryController.IsPowerPresent();
bleState = bleController.IsConnected();
batteryPercentRemaining = batteryController.PercentRemaining();
if (batteryPercentRemaining.IsUpdated() || powerPresent.IsUpdated()) {
lv_label_set_text_fmt(batteryValue, "#ffffff %d%%#", batteryPercentRemaining.Get());
if (batteryController.IsPowerPresent()) {
lv_label_ins_text(batteryValue, LV_LABEL_POS_LAST, " Charging");
}
}
if (bleState.IsUpdated()) {
if (bleState.Get()) {
lv_label_set_text_static(bluetoothStatus, Symbols::bluetooth);
} else {
lv_label_set_text_static(bluetoothStatus, "");
}
}

notificationState = notificationManager.AreNewNotificationsAvailable();
if (notificationState.IsUpdated()) {
if (notificationState.Get()) {
lv_label_set_text_static(notificationIcon, "You have\nmail!");
} else {
lv_label_set_text_static(notificationIcon, "");
}
}

currentDateTime = std::chrono::time_point_cast<std::chrono::seconds>(dateTimeController.CurrentDateTime());
if (currentDateTime.IsUpdated()) {
uint8_t hour = dateTimeController.Hours();
uint8_t minute = dateTimeController.Minutes();
uint8_t second = dateTimeController.Seconds();

if (settingsController.GetClockType() == Controllers::Settings::ClockType::H12) {
if (hour == 0) {
ampmChar = "AM";
hour = 12;
} else if (hour == 12) {
ampmChar = "PM";
} else if (hour > 12) {
hour = hour - 12;
ampmChar = "PM";
}
}

lv_label_set_text_fmt(labelTime, "#000000 %02d:%02d:%02d#", hour, minute, second);

currentDate = std::chrono::time_point_cast<std::chrono::days>(currentDateTime.Get());
if (currentDate.IsUpdated() || ampmChar.IsUpdated()) {
uint16_t year = dateTimeController.Year();
Controllers::DateTime::Months month = dateTimeController.Month();
uint8_t day = dateTimeController.Day();
Controllers::DateTime::Days dayOfWeek = dateTimeController.DayOfWeek();
lv_label_set_text_fmt(labelDate, "#ffffff %02d-%02d-%04d#", day, static_cast<uint8_t>(month), year);
if (settingsController.GetClockType() == Controllers::Settings::ClockType::H12) {
lv_label_set_text_fmt(labelDay, "#ffffff %s %s#", dateTimeController.DayOfWeekToStringLow(dayOfWeek), ampmChar);
} else {
lv_label_set_text_fmt(labelDay, "#ffffff %s#", dateTimeController.DayOfWeekToStringLow(dayOfWeek));
}
}
}

stepCount = motionController.NbSteps();
if (stepCount.IsUpdated()) {
lv_label_set_text_fmt(stepValue, "#ffffff %lu steps#", stepCount.Get());
}
}
95 changes: 95 additions & 0 deletions src/displayapp/screens/WatchFaceTrans.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#pragma once

#include <lvgl/src/lv_core/lv_obj.h>
#include <chrono>
#include <cstdint>
#include <memory>
#include <displayapp/Controllers.h>
#include "displayapp/screens/Screen.h"
#include "displayapp/widgets/StatusIcons.h"
#include "components/datetime/DateTimeController.h"
#include "components/ble/BleController.h"
#include "utility/DirtyValue.h"

namespace Pinetime {
namespace Controllers {
class Settings;
class Battery;
class Ble;
class NotificationManager;
class MotionController;
}

namespace Applications {
namespace Screens {

class WatchFaceTrans : public Screen {
public:
WatchFaceTrans(Controllers::DateTime& dateTimeController,
const Controllers::Battery& batteryController,
const Controllers::Ble& bleController,
Controllers::NotificationManager& notificationManager,
Controllers::Settings& settingsController,
Controllers::MotionController& motionController);
~WatchFaceTrans() override;

void Refresh() override;

private:
Utility::DirtyValue<uint8_t> batteryPercentRemaining {};
Utility::DirtyValue<bool> powerPresent {};
Utility::DirtyValue<bool> bleState {};
Utility::DirtyValue<std::chrono::time_point<std::chrono::system_clock, std::chrono::seconds>> currentDateTime {};
Utility::DirtyValue<uint32_t> stepCount {};
Utility::DirtyValue<bool> notificationState {};
Utility::DirtyValue<std::chrono::time_point<std::chrono::system_clock, std::chrono::days>> currentDate;
// Must be wrapped in a dirty value, since it is displayed in the day but is updated twice a day
Utility::DirtyValue<const char*> ampmChar {"AM"};

lv_obj_t* topBlueBackground;
lv_obj_t* topPinkBackground;
lv_obj_t* whiteBackground;
lv_obj_t* bottomPinkBackground;
lv_obj_t* bottomBlueBackground;
lv_obj_t* bluetoothStatus;
lv_obj_t* labelTime;
lv_obj_t* labelDate;
lv_obj_t* labelDay;
lv_obj_t* batteryValue;
lv_obj_t* stepValue;
lv_obj_t* notificationIcon;

static constexpr lv_color_t lightBlue = LV_COLOR_MAKE(0x00, 0xbf, 0xf3);
static constexpr lv_color_t lightPink = LV_COLOR_MAKE(0xf4, 0x9a, 0xc1);

Controllers::DateTime& dateTimeController;
const Controllers::Battery& batteryController;
const Controllers::Ble bleController;
Controllers::NotificationManager& notificationManager;
Controllers::Settings& settingsController;
Controllers::MotionController& motionController;

lv_task_t* taskRefresh;
};
}

template <>
struct WatchFaceTraits<WatchFace::Trans> {
static constexpr WatchFace watchFace = WatchFace::Trans;
static constexpr const char* name = "Trans Flag";

static Screens::Screen* Create(AppControllers& controllers) {
return new Screens::WatchFaceTrans(controllers.dateTimeController,
controllers.batteryController,
controllers.bleController,
controllers.notificationManager,
controllers.settingsController,
controllers.motionController);
};

static bool IsAvailable(Pinetime::Controllers::FS& /*filesystem*/) {
return true;
}
};
}
}
Loading