mirror of
https://github.com/InfiniTimeOrg/InfiniTime.git
synced 2024-10-22 15:11:51 +02:00
Compare commits
12 commits
d2df162d08
...
6bdba5cd07
Author | SHA1 | Date | |
---|---|---|---|
6bdba5cd07 | |||
a2356f2f4a | |||
3db4e012ce | |||
a0cd439efc | |||
f9add3637e | |||
2d47679212 | |||
e2e063cb37 | |||
3905b3bafd | |||
e25ca95c47 | |||
206c88c0da | |||
3915d3a344 | |||
f6731c1a5a |
|
@ -426,6 +426,7 @@ list(APPEND SOURCE_FILES
|
|||
displayapp/screens/WatchFaceTerminal.cpp
|
||||
displayapp/screens/WatchFacePineTimeStyle.cpp
|
||||
displayapp/screens/WatchFaceCasioStyleG7710.cpp
|
||||
displayapp/screens/WatchFaceNumerals.cpp
|
||||
|
||||
##
|
||||
|
||||
|
|
|
@ -19,11 +19,13 @@
|
|||
#include "systemtask/SystemTask.h"
|
||||
#include "task.h"
|
||||
#include <chrono>
|
||||
#include <libraries/log/nrf_log.h>
|
||||
|
||||
using namespace Pinetime::Controllers;
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
AlarmController::AlarmController(Controllers::DateTime& dateTimeController) : dateTimeController {dateTimeController} {
|
||||
AlarmController::AlarmController(Controllers::DateTime& dateTimeController, Controllers::FS& fs)
|
||||
: dateTimeController {dateTimeController}, fs {fs} {
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
@ -36,11 +38,28 @@ namespace {
|
|||
void AlarmController::Init(System::SystemTask* systemTask) {
|
||||
this->systemTask = systemTask;
|
||||
alarmTimer = xTimerCreate("Alarm", 1, pdFALSE, this, SetOffAlarm);
|
||||
LoadSettingsFromFile();
|
||||
if (alarm.isEnabled) {
|
||||
NRF_LOG_INFO("[AlarmController] Loaded alarm was enabled, scheduling");
|
||||
ScheduleAlarm();
|
||||
}
|
||||
}
|
||||
|
||||
void AlarmController::SaveAlarm() {
|
||||
// verify if it is necessary to save
|
||||
if (alarmChanged) {
|
||||
SaveSettingsToFile();
|
||||
}
|
||||
alarmChanged = false;
|
||||
}
|
||||
|
||||
void AlarmController::SetAlarmTime(uint8_t alarmHr, uint8_t alarmMin) {
|
||||
hours = alarmHr;
|
||||
minutes = alarmMin;
|
||||
if (alarm.hours == alarmHr && alarm.minutes == alarmMin) {
|
||||
return;
|
||||
}
|
||||
alarm.hours = alarmHr;
|
||||
alarm.minutes = alarmMin;
|
||||
alarmChanged = true;
|
||||
}
|
||||
|
||||
void AlarmController::ScheduleAlarm() {
|
||||
|
@ -53,18 +72,19 @@ void AlarmController::ScheduleAlarm() {
|
|||
tm* tmAlarmTime = std::localtime(&ttAlarmTime);
|
||||
|
||||
// If the time being set has already passed today,the alarm should be set for tomorrow
|
||||
if (hours < dateTimeController.Hours() || (hours == dateTimeController.Hours() && minutes <= dateTimeController.Minutes())) {
|
||||
if (alarm.hours < dateTimeController.Hours() ||
|
||||
(alarm.hours == dateTimeController.Hours() && alarm.minutes <= dateTimeController.Minutes())) {
|
||||
tmAlarmTime->tm_mday += 1;
|
||||
// tm_wday doesn't update automatically
|
||||
tmAlarmTime->tm_wday = (tmAlarmTime->tm_wday + 1) % 7;
|
||||
}
|
||||
|
||||
tmAlarmTime->tm_hour = hours;
|
||||
tmAlarmTime->tm_min = minutes;
|
||||
tmAlarmTime->tm_hour = alarm.hours;
|
||||
tmAlarmTime->tm_min = alarm.minutes;
|
||||
tmAlarmTime->tm_sec = 0;
|
||||
|
||||
// if alarm is in weekday-only mode, make sure it shifts to the next weekday
|
||||
if (recurrence == RecurType::Weekdays) {
|
||||
if (alarm.recurrence == RecurType::Weekdays) {
|
||||
if (tmAlarmTime->tm_wday == 0) { // Sunday, shift 1 day
|
||||
tmAlarmTime->tm_mday += 1;
|
||||
} else if (tmAlarmTime->tm_wday == 6) { // Saturday, shift 2 days
|
||||
|
@ -79,7 +99,10 @@ void AlarmController::ScheduleAlarm() {
|
|||
xTimerChangePeriod(alarmTimer, secondsToAlarm * configTICK_RATE_HZ, 0);
|
||||
xTimerStart(alarmTimer, 0);
|
||||
|
||||
state = AlarmState::Set;
|
||||
if (!alarm.isEnabled) {
|
||||
alarm.isEnabled = true;
|
||||
alarmChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t AlarmController::SecondsToAlarm() const {
|
||||
|
@ -88,20 +111,72 @@ uint32_t AlarmController::SecondsToAlarm() const {
|
|||
|
||||
void AlarmController::DisableAlarm() {
|
||||
xTimerStop(alarmTimer, 0);
|
||||
state = AlarmState::Not_Set;
|
||||
isAlerting = false;
|
||||
if (alarm.isEnabled) {
|
||||
alarm.isEnabled = false;
|
||||
alarmChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void AlarmController::SetOffAlarmNow() {
|
||||
state = AlarmState::Alerting;
|
||||
isAlerting = true;
|
||||
systemTask->PushMessage(System::Messages::SetOffAlarm);
|
||||
}
|
||||
|
||||
void AlarmController::StopAlerting() {
|
||||
// Alarm state is off unless this is a recurring alarm
|
||||
if (recurrence == RecurType::None) {
|
||||
state = AlarmState::Not_Set;
|
||||
isAlerting = false;
|
||||
// Disable alarm unless it is recurring
|
||||
if (alarm.recurrence == RecurType::None) {
|
||||
alarm.isEnabled = false;
|
||||
alarmChanged = true;
|
||||
} else {
|
||||
// set next instance
|
||||
ScheduleAlarm();
|
||||
}
|
||||
}
|
||||
|
||||
void AlarmController::SetRecurrence(RecurType recurrence) {
|
||||
if (alarm.recurrence != recurrence) {
|
||||
alarm.recurrence = recurrence;
|
||||
alarmChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void AlarmController::LoadSettingsFromFile() {
|
||||
lfs_file_t alarmFile;
|
||||
AlarmSettings alarmBuffer;
|
||||
|
||||
if (fs.FileOpen(&alarmFile, "/.system/alarm.dat", LFS_O_RDONLY) != LFS_ERR_OK) {
|
||||
NRF_LOG_WARNING("[AlarmController] Failed to open alarm data file");
|
||||
return;
|
||||
}
|
||||
|
||||
fs.FileRead(&alarmFile, reinterpret_cast<uint8_t*>(&alarmBuffer), sizeof(alarmBuffer));
|
||||
fs.FileClose(&alarmFile);
|
||||
if (alarmBuffer.version != alarmFormatVersion) {
|
||||
NRF_LOG_WARNING("[AlarmController] Loaded alarm settings has version %u instead of %u, discarding",
|
||||
alarmBuffer.version,
|
||||
alarmFormatVersion);
|
||||
return;
|
||||
}
|
||||
|
||||
alarm = alarmBuffer;
|
||||
NRF_LOG_INFO("[AlarmController] Loaded alarm settings from file");
|
||||
}
|
||||
|
||||
void AlarmController::SaveSettingsToFile() const {
|
||||
lfs_dir systemDir;
|
||||
if (fs.DirOpen("/.system", &systemDir) != LFS_ERR_OK) {
|
||||
fs.DirCreate("/.system");
|
||||
}
|
||||
fs.DirClose(&systemDir);
|
||||
lfs_file_t alarmFile;
|
||||
if (fs.FileOpen(&alarmFile, "/.system/alarm.dat", LFS_O_WRONLY | LFS_O_CREAT) != LFS_ERR_OK) {
|
||||
NRF_LOG_WARNING("[AlarmController] Failed to open alarm data file for saving");
|
||||
return;
|
||||
}
|
||||
|
||||
fs.FileWrite(&alarmFile, reinterpret_cast<const uint8_t*>(&alarm), sizeof(alarm));
|
||||
fs.FileClose(&alarmFile);
|
||||
NRF_LOG_INFO("[AlarmController] Saved alarm settings with format version %u to file", alarm.version);
|
||||
}
|
||||
|
|
|
@ -30,47 +30,65 @@ namespace Pinetime {
|
|||
namespace Controllers {
|
||||
class AlarmController {
|
||||
public:
|
||||
AlarmController(Controllers::DateTime& dateTimeController);
|
||||
AlarmController(Controllers::DateTime& dateTimeController, Controllers::FS& fs);
|
||||
|
||||
void Init(System::SystemTask* systemTask);
|
||||
void SaveAlarm();
|
||||
void SetAlarmTime(uint8_t alarmHr, uint8_t alarmMin);
|
||||
void ScheduleAlarm();
|
||||
void DisableAlarm();
|
||||
void SetOffAlarmNow();
|
||||
uint32_t SecondsToAlarm() const;
|
||||
void StopAlerting();
|
||||
enum class AlarmState { Not_Set, Set, Alerting };
|
||||
enum class RecurType { None, Daily, Weekdays };
|
||||
|
||||
uint8_t Hours() const {
|
||||
return hours;
|
||||
return alarm.hours;
|
||||
}
|
||||
|
||||
uint8_t Minutes() const {
|
||||
return minutes;
|
||||
return alarm.minutes;
|
||||
}
|
||||
|
||||
AlarmState State() const {
|
||||
return state;
|
||||
bool IsAlerting() const {
|
||||
return isAlerting;
|
||||
}
|
||||
|
||||
bool IsEnabled() const {
|
||||
return alarm.isEnabled;
|
||||
}
|
||||
|
||||
RecurType Recurrence() const {
|
||||
return recurrence;
|
||||
return alarm.recurrence;
|
||||
}
|
||||
|
||||
void SetRecurrence(RecurType recurType) {
|
||||
recurrence = recurType;
|
||||
}
|
||||
void SetRecurrence(RecurType recurrence);
|
||||
|
||||
private:
|
||||
// Versions 255 is reserved for now, so the version field can be made
|
||||
// bigger, should it ever be needed.
|
||||
static constexpr uint8_t alarmFormatVersion = 1;
|
||||
|
||||
struct AlarmSettings {
|
||||
uint8_t version = alarmFormatVersion;
|
||||
uint8_t hours = 7;
|
||||
uint8_t minutes = 0;
|
||||
RecurType recurrence = RecurType::None;
|
||||
bool isEnabled = false;
|
||||
};
|
||||
|
||||
bool isAlerting = false;
|
||||
bool alarmChanged = false;
|
||||
|
||||
Controllers::DateTime& dateTimeController;
|
||||
Controllers::FS& fs;
|
||||
System::SystemTask* systemTask = nullptr;
|
||||
TimerHandle_t alarmTimer;
|
||||
uint8_t hours = 7;
|
||||
uint8_t minutes = 0;
|
||||
AlarmSettings alarm;
|
||||
std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> alarmTime;
|
||||
AlarmState state = AlarmState::Not_Set;
|
||||
RecurType recurrence = RecurType::None;
|
||||
|
||||
void LoadSettingsFromFile();
|
||||
void SaveSettingsToFile() const;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
#include "components/ble/MusicService.h"
|
||||
#include "components/ble/NimbleController.h"
|
||||
#include <cstring>
|
||||
#include <FreeRTOS.h>
|
||||
#include <task.h>
|
||||
|
||||
namespace {
|
||||
// 0000yyxx-78fc-48fe-8e23-433b3a1942d0
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <host/ble_uuid.h>
|
||||
#undef max
|
||||
#undef min
|
||||
#include <FreeRTOS.h>
|
||||
|
||||
namespace Pinetime {
|
||||
namespace Controllers {
|
||||
|
|
|
@ -582,7 +582,7 @@ void DisplayApp::LoadScreen(Apps app, DisplayApp::FullRefreshDirections directio
|
|||
currentScreen = std::make_unique<Screens::SettingWakeUp>(settingsController);
|
||||
break;
|
||||
case Apps::SettingDisplay:
|
||||
currentScreen = std::make_unique<Screens::SettingDisplay>(this, settingsController);
|
||||
currentScreen = std::make_unique<Screens::SettingDisplay>(settingsController);
|
||||
break;
|
||||
case Apps::SettingSteps:
|
||||
currentScreen = std::make_unique<Screens::SettingSteps>(settingsController);
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "displayapp/screens/WatchFaceInfineat.h"
|
||||
#include "displayapp/screens/WatchFacePineTimeStyle.h"
|
||||
#include "displayapp/screens/WatchFaceTerminal.h"
|
||||
#include "displayapp/screens/WatchFaceNumerals.h"
|
||||
|
||||
namespace Pinetime {
|
||||
namespace Applications {
|
||||
|
|
|
@ -52,6 +52,7 @@ namespace Pinetime {
|
|||
Terminal,
|
||||
Infineat,
|
||||
CasioStyleG7710,
|
||||
Numerals,
|
||||
};
|
||||
|
||||
template <Apps>
|
||||
|
|
|
@ -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::Numerals")
|
||||
set(WATCHFACE_TYPES "${DEFAULT_WATCHFACE_TYPES}" CACHE STRING "List of watch faces to build into the firmware")
|
||||
endif()
|
||||
|
||||
|
|
|
@ -117,7 +117,7 @@ Alarm::Alarm(Controllers::AlarmController& alarmController,
|
|||
|
||||
UpdateAlarmTime();
|
||||
|
||||
if (alarmController.State() == Controllers::AlarmController::AlarmState::Alerting) {
|
||||
if (alarmController.IsAlerting()) {
|
||||
SetAlerting();
|
||||
} else {
|
||||
SetSwitchState(LV_ANIM_OFF);
|
||||
|
@ -125,14 +125,15 @@ Alarm::Alarm(Controllers::AlarmController& alarmController,
|
|||
}
|
||||
|
||||
Alarm::~Alarm() {
|
||||
if (alarmController.State() == AlarmController::AlarmState::Alerting) {
|
||||
if (alarmController.IsAlerting()) {
|
||||
StopAlerting();
|
||||
}
|
||||
lv_obj_clean(lv_scr_act());
|
||||
alarmController.SaveAlarm();
|
||||
}
|
||||
|
||||
void Alarm::DisableAlarm() {
|
||||
if (alarmController.State() == AlarmController::AlarmState::Set) {
|
||||
if (alarmController.IsEnabled()) {
|
||||
alarmController.DisableAlarm();
|
||||
lv_switch_off(enableSwitch, LV_ANIM_ON);
|
||||
}
|
||||
|
@ -172,7 +173,7 @@ bool Alarm::OnButtonPushed() {
|
|||
HideInfo();
|
||||
return true;
|
||||
}
|
||||
if (alarmController.State() == AlarmController::AlarmState::Alerting) {
|
||||
if (alarmController.IsAlerting()) {
|
||||
StopAlerting();
|
||||
return true;
|
||||
}
|
||||
|
@ -181,7 +182,7 @@ bool Alarm::OnButtonPushed() {
|
|||
|
||||
bool Alarm::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
|
||||
// Don't allow closing the screen by swiping while the alarm is alerting
|
||||
return alarmController.State() == AlarmController::AlarmState::Alerting && event == TouchEvents::SwipeDown;
|
||||
return alarmController.IsAlerting() && event == TouchEvents::SwipeDown;
|
||||
}
|
||||
|
||||
void Alarm::OnValueChanged() {
|
||||
|
@ -222,15 +223,10 @@ void Alarm::StopAlerting() {
|
|||
}
|
||||
|
||||
void Alarm::SetSwitchState(lv_anim_enable_t anim) {
|
||||
switch (alarmController.State()) {
|
||||
case AlarmController::AlarmState::Set:
|
||||
lv_switch_on(enableSwitch, anim);
|
||||
break;
|
||||
case AlarmController::AlarmState::Not_Set:
|
||||
lv_switch_off(enableSwitch, anim);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if (alarmController.IsEnabled()) {
|
||||
lv_switch_on(enableSwitch, anim);
|
||||
} else {
|
||||
lv_switch_off(enableSwitch, anim);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -247,7 +243,7 @@ void Alarm::ShowInfo() {
|
|||
txtMessage = lv_label_create(btnMessage, nullptr);
|
||||
lv_obj_set_style_local_bg_color(btnMessage, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_NAVY);
|
||||
|
||||
if (alarmController.State() == AlarmController::AlarmState::Set) {
|
||||
if (alarmController.IsEnabled()) {
|
||||
auto timeToAlarm = alarmController.SecondsToAlarm();
|
||||
|
||||
auto daysToAlarm = timeToAlarm / 86400;
|
||||
|
|
|
@ -40,8 +40,7 @@ SystemInfo::SystemInfo(Pinetime::Applications::DisplayApp* app,
|
|||
Pinetime::Controllers::MotionController& motionController,
|
||||
const Pinetime::Drivers::Cst816S& touchPanel,
|
||||
const Pinetime::Drivers::SpiNorFlash& spiNorFlash)
|
||||
: app {app},
|
||||
dateTimeController {dateTimeController},
|
||||
: dateTimeController {dateTimeController},
|
||||
batteryController {batteryController},
|
||||
brightnessController {brightnessController},
|
||||
bleController {bleController},
|
||||
|
|
|
@ -35,7 +35,6 @@ namespace Pinetime {
|
|||
bool OnTouchEvent(TouchEvents event) override;
|
||||
|
||||
private:
|
||||
DisplayApp* app;
|
||||
Pinetime::Controllers::DateTime& dateTimeController;
|
||||
const Pinetime::Controllers::Battery& batteryController;
|
||||
Pinetime::Controllers::BrightnessController& brightnessController;
|
||||
|
|
155
src/displayapp/screens/WatchFaceNumerals.cpp
Normal file
155
src/displayapp/screens/WatchFaceNumerals.cpp
Normal file
|
@ -0,0 +1,155 @@
|
|||
#include "displayapp/screens/WatchFaceNumerals.h"
|
||||
|
||||
#include <lvgl/lvgl.h>
|
||||
#include <cstdio>
|
||||
#include "displayapp/screens/Symbols.h"
|
||||
#include "components/ble/NotificationManager.h"
|
||||
#include "components/settings/Settings.h"
|
||||
|
||||
using namespace Pinetime::Applications::Screens;
|
||||
|
||||
WatchFaceNumerals::WatchFaceNumerals(Controllers::DateTime& dateTimeController,
|
||||
Controllers::NotificationManager& notificationManager,
|
||||
Controllers::Settings& settingsController,
|
||||
Controllers::FS& filesystem)
|
||||
: currentDateTime {{}},
|
||||
dateTimeController {dateTimeController},
|
||||
notificationManager {notificationManager},
|
||||
settingsController {settingsController} {
|
||||
|
||||
lfs_file f = {};
|
||||
if (filesystem.FileOpen(&f, "/fonts/rounded_large.bin", LFS_O_RDONLY) >= 0) {
|
||||
filesystem.FileClose(&f);
|
||||
font_large = lv_font_load("F:/fonts/rounded_large.bin");
|
||||
}
|
||||
|
||||
if (filesystem.FileOpen(&f, "/fonts/rounded_small.bin", LFS_O_RDONLY) >= 0) {
|
||||
filesystem.FileClose(&f);
|
||||
font_small = lv_font_load("F:/fonts/rounded_small.bin");
|
||||
}
|
||||
|
||||
notificationIcon = lv_obj_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_style_local_bg_color(notificationIcon, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_AQUA);
|
||||
lv_obj_set_style_local_radius(notificationIcon, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE);
|
||||
lv_obj_set_size(notificationIcon, 16, 16);
|
||||
lv_obj_align(notificationIcon, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 4, -76);
|
||||
lv_obj_set_hidden(notificationIcon, true);
|
||||
|
||||
labelTimeHour = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_style_local_text_font(labelTimeHour, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_large);
|
||||
lv_obj_set_style_local_text_color(labelTimeHour, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY);
|
||||
lv_obj_align(labelTimeHour, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, -160, -125);
|
||||
|
||||
labelTimeMinute = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_style_local_text_font(labelTimeMinute, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_large);
|
||||
lv_obj_set_style_local_text_color(labelTimeMinute, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_AQUA);
|
||||
lv_obj_align(labelTimeMinute, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, -160, 0);
|
||||
|
||||
labelTimeAMPM1 = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_label_set_text_static(labelTimeAMPM1, "");
|
||||
lv_obj_set_style_local_text_font(labelTimeAMPM1, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_small);
|
||||
lv_obj_set_style_local_text_color(labelTimeAMPM1, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x999999));
|
||||
lv_obj_align(labelTimeAMPM1, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 2, -34);
|
||||
|
||||
labelTimeAMPM2 = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_label_set_text_static(labelTimeAMPM2, "M");
|
||||
lv_obj_set_style_local_text_font(labelTimeAMPM2, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_small);
|
||||
lv_obj_set_style_local_text_color(labelTimeAMPM2, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x999999));
|
||||
lv_obj_align(labelTimeAMPM2, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 0, 0);
|
||||
|
||||
dateDayOfWeek = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_style_local_text_color(dateDayOfWeek, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE);
|
||||
lv_label_set_text(dateDayOfWeek, "---");
|
||||
lv_obj_set_style_local_text_font(dateDayOfWeek, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_small);
|
||||
lv_obj_align(dateDayOfWeek, lv_scr_act(), LV_ALIGN_IN_TOP_LEFT, 0, 0);
|
||||
|
||||
dateDay = lv_label_create(lv_scr_act(), nullptr);
|
||||
lv_obj_set_style_local_text_color(dateDay, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE);
|
||||
lv_label_set_text(dateDay, "--");
|
||||
lv_obj_set_style_local_text_font(dateDay, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font_small);
|
||||
lv_obj_align(dateDay, lv_scr_act(), LV_ALIGN_IN_TOP_LEFT, 0, 36);
|
||||
|
||||
taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this);
|
||||
Refresh();
|
||||
}
|
||||
|
||||
WatchFaceNumerals::~WatchFaceNumerals() {
|
||||
lv_task_del(taskRefresh);
|
||||
|
||||
if (font_large != nullptr) {
|
||||
lv_font_free(font_large);
|
||||
}
|
||||
if (font_small != nullptr) {
|
||||
lv_font_free(font_small);
|
||||
}
|
||||
|
||||
lv_obj_clean(lv_scr_act());
|
||||
}
|
||||
|
||||
void WatchFaceNumerals::Refresh() {
|
||||
notificationState = notificationManager.AreNewNotificationsAvailable();
|
||||
if (notificationState.IsUpdated()) {
|
||||
lv_obj_set_hidden(notificationIcon, !notificationState.Get());
|
||||
}
|
||||
|
||||
currentDateTime = dateTimeController.CurrentDateTime();
|
||||
if (currentDateTime.IsUpdated()) {
|
||||
auto hour = dateTimeController.Hours();
|
||||
auto minute = dateTimeController.Minutes();
|
||||
auto year = dateTimeController.Year();
|
||||
auto month = dateTimeController.Month();
|
||||
auto dayOfWeek = dateTimeController.DayOfWeek();
|
||||
auto day = dateTimeController.Day();
|
||||
|
||||
if (displayedHour != hour || displayedMinute != minute) {
|
||||
displayedHour = hour;
|
||||
displayedMinute = minute;
|
||||
|
||||
if (settingsController.GetClockType() == Controllers::Settings::ClockType::H12) {
|
||||
char ampmChar[2] = "A";
|
||||
if (hour == 0) {
|
||||
hour = 12;
|
||||
} else if (hour == 12) {
|
||||
ampmChar[0] = 'P';
|
||||
} else if (hour > 12) {
|
||||
hour = hour - 12;
|
||||
ampmChar[0] = 'P';
|
||||
}
|
||||
lv_label_set_text(labelTimeAMPM1, ampmChar);
|
||||
lv_label_set_text_fmt(labelTimeHour, "%02d", hour);
|
||||
lv_label_set_text_fmt(labelTimeMinute, "%02d", minute);
|
||||
} else {
|
||||
lv_obj_set_hidden(labelTimeAMPM2, true);
|
||||
lv_label_set_text_fmt(labelTimeHour, "%02d", hour);
|
||||
lv_label_set_text_fmt(labelTimeMinute, "%02d", minute);
|
||||
}
|
||||
}
|
||||
|
||||
if ((year != currentYear) || (month != currentMonth) || (dayOfWeek != currentDayOfWeek) || (day != currentDay)) {
|
||||
lv_label_set_text_static(dateDayOfWeek, dateTimeController.DayOfWeekShortToString());
|
||||
lv_label_set_text_fmt(dateDay, "%d", day);
|
||||
lv_obj_realign(dateDay);
|
||||
|
||||
currentYear = year;
|
||||
currentMonth = month;
|
||||
currentDayOfWeek = dayOfWeek;
|
||||
currentDay = day;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool WatchFaceNumerals::IsAvailable(Pinetime::Controllers::FS& filesystem) {
|
||||
lfs_file file = {};
|
||||
|
||||
if (filesystem.FileOpen(&file, "/fonts/rounded_small.bin", LFS_O_RDONLY) < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
filesystem.FileClose(&file);
|
||||
if (filesystem.FileOpen(&file, "/fonts/rounded_large.bin", LFS_O_RDONLY) < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
filesystem.FileClose(&file);
|
||||
return true;
|
||||
}
|
82
src/displayapp/screens/WatchFaceNumerals.h
Normal file
82
src/displayapp/screens/WatchFaceNumerals.h
Normal file
|
@ -0,0 +1,82 @@
|
|||
#pragma once
|
||||
|
||||
#include <lvgl/lvgl.h>
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <displayapp/Controllers.h>
|
||||
#include "displayapp/screens/Screen.h"
|
||||
#include "components/datetime/DateTimeController.h"
|
||||
#include "utility/DirtyValue.h"
|
||||
#include "displayapp/apps/Apps.h"
|
||||
|
||||
namespace Pinetime {
|
||||
namespace Controllers {
|
||||
class Settings;
|
||||
class NotificationManager;
|
||||
}
|
||||
|
||||
namespace Applications {
|
||||
namespace Screens {
|
||||
|
||||
class WatchFaceNumerals : public Screen {
|
||||
public:
|
||||
WatchFaceNumerals(Controllers::DateTime& dateTimeController,
|
||||
Controllers::NotificationManager& notificationManager,
|
||||
Controllers::Settings& settingsController,
|
||||
Controllers::FS& fs);
|
||||
~WatchFaceNumerals() override;
|
||||
|
||||
void Refresh() override;
|
||||
|
||||
static bool IsAvailable(Pinetime::Controllers::FS& filesystem);
|
||||
|
||||
private:
|
||||
uint8_t displayedHour = -1;
|
||||
uint8_t displayedMinute = -1;
|
||||
|
||||
uint16_t currentYear = 1970;
|
||||
Controllers::DateTime::Months currentMonth = Pinetime::Controllers::DateTime::Months::Unknown;
|
||||
Controllers::DateTime::Days currentDayOfWeek = Pinetime::Controllers::DateTime::Days::Unknown;
|
||||
uint8_t currentDay = 0;
|
||||
Utility::DirtyValue<bool> notificationState {};
|
||||
Utility::DirtyValue<std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds>> currentDateTime {};
|
||||
|
||||
lv_obj_t* labelTimeHour;
|
||||
lv_obj_t* labelTimeMinute;
|
||||
lv_obj_t* labelTimeAMPM1;
|
||||
lv_obj_t* labelTimeAMPM2;
|
||||
lv_obj_t* label_date;
|
||||
lv_obj_t* notificationIcon;
|
||||
lv_obj_t* dateDay;
|
||||
lv_obj_t* dateDayOfWeek;
|
||||
|
||||
Controllers::DateTime& dateTimeController;
|
||||
Controllers::NotificationManager& notificationManager;
|
||||
Controllers::Settings& settingsController;
|
||||
|
||||
lv_font_t* font_large = nullptr;
|
||||
lv_font_t* font_small = nullptr;
|
||||
|
||||
lv_task_t* taskRefresh;
|
||||
};
|
||||
}
|
||||
|
||||
template <>
|
||||
struct WatchFaceTraits<WatchFace::Numerals> {
|
||||
static constexpr WatchFace watchFace = WatchFace::Numerals;
|
||||
static constexpr const char* name = "Numerals";
|
||||
|
||||
static Screens::Screen* Create(AppControllers& controllers) {
|
||||
return new Screens::WatchFaceNumerals(controllers.dateTimeController,
|
||||
controllers.notificationManager,
|
||||
controllers.settingsController,
|
||||
controllers.filesystem);
|
||||
};
|
||||
|
||||
static bool IsAvailable(Pinetime::Controllers::FS& filesystem) {
|
||||
return Screens::WatchFaceNumerals::IsAvailable(filesystem);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -24,8 +24,7 @@ namespace {
|
|||
|
||||
constexpr std::array<uint16_t, 6> SettingDisplay::options;
|
||||
|
||||
SettingDisplay::SettingDisplay(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Settings& settingsController)
|
||||
: app {app}, settingsController {settingsController} {
|
||||
SettingDisplay::SettingDisplay(Pinetime::Controllers::Settings& settingsController) : settingsController {settingsController} {
|
||||
|
||||
lv_obj_t* container1 = lv_cont_create(lv_scr_act(), nullptr);
|
||||
|
||||
|
|
|
@ -14,14 +14,13 @@ namespace Pinetime {
|
|||
|
||||
class SettingDisplay : public Screen {
|
||||
public:
|
||||
SettingDisplay(DisplayApp* app, Pinetime::Controllers::Settings& settingsController);
|
||||
SettingDisplay(Pinetime::Controllers::Settings& settingsController);
|
||||
~SettingDisplay() override;
|
||||
|
||||
void UpdateSelected(lv_obj_t* object, lv_event_t event);
|
||||
void ToggleAlwaysOn();
|
||||
|
||||
private:
|
||||
DisplayApp* app;
|
||||
static constexpr std::array<uint16_t, 6> options = {5000, 7000, 10000, 15000, 20000, 30000};
|
||||
|
||||
Controllers::Settings& settingsController;
|
||||
|
|
|
@ -15,8 +15,7 @@ bool SettingSetDateTime::OnTouchEvent(Pinetime::Applications::TouchEvents event)
|
|||
SettingSetDateTime::SettingSetDateTime(Pinetime::Applications::DisplayApp* app,
|
||||
Pinetime::Controllers::DateTime& dateTimeController,
|
||||
Pinetime::Controllers::Settings& settingsController)
|
||||
: app {app},
|
||||
dateTimeController {dateTimeController},
|
||||
: dateTimeController {dateTimeController},
|
||||
settingsController {settingsController},
|
||||
screens {app,
|
||||
0,
|
||||
|
|
|
@ -20,7 +20,6 @@ namespace Pinetime {
|
|||
void Quit();
|
||||
|
||||
private:
|
||||
DisplayApp* app;
|
||||
Controllers::DateTime& dateTimeController;
|
||||
Controllers::Settings& settingsController;
|
||||
|
||||
|
|
|
@ -54,8 +54,7 @@ SettingWatchFace::SettingWatchFace(Pinetime::Applications::DisplayApp* app,
|
|||
std::array<Screens::SettingWatchFace::Item, UserWatchFaceTypes::Count>&& watchfaceItems,
|
||||
Pinetime::Controllers::Settings& settingsController,
|
||||
Pinetime::Controllers::FS& filesystem)
|
||||
: app {app},
|
||||
watchfaceItems {std::move(watchfaceItems)},
|
||||
: watchfaceItems {std::move(watchfaceItems)},
|
||||
settingsController {settingsController},
|
||||
filesystem {filesystem},
|
||||
screens {app, 0, CreateScreenList(), Screens::ScreenListModes::UpDown} {
|
||||
|
|
|
@ -34,7 +34,6 @@ namespace Pinetime {
|
|||
bool OnTouchEvent(TouchEvents event) override;
|
||||
|
||||
private:
|
||||
DisplayApp* app;
|
||||
auto CreateScreenList() const;
|
||||
std::unique_ptr<Screen> CreateScreen(unsigned int screenNum) const;
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ Pinetime::Controllers::DateTime dateTimeController {settingsController};
|
|||
Pinetime::Drivers::Watchdog watchdog;
|
||||
Pinetime::Controllers::NotificationManager notificationManager;
|
||||
Pinetime::Controllers::MotionController motionController;
|
||||
Pinetime::Controllers::AlarmController alarmController {dateTimeController};
|
||||
Pinetime::Controllers::AlarmController alarmController {dateTimeController, fs};
|
||||
Pinetime::Controllers::TouchHandler touchHandler;
|
||||
Pinetime::Controllers::ButtonHandler buttonHandler;
|
||||
Pinetime::Controllers::BrightnessController brightnessController {};
|
||||
|
|
|
@ -58,5 +58,29 @@
|
|||
"size": 115,
|
||||
"format": "bin",
|
||||
"target_path": "/fonts/"
|
||||
},
|
||||
"rounded_large": {
|
||||
"sources": [
|
||||
{
|
||||
"file": "fonts/BloggerSans-Bold.ttf",
|
||||
"range": "0x30-0x3a"
|
||||
}
|
||||
],
|
||||
"bpp": 1,
|
||||
"size": 150,
|
||||
"format": "bin",
|
||||
"target_path": "/fonts/"
|
||||
},
|
||||
"rounded_small": {
|
||||
"sources": [
|
||||
{
|
||||
"file": "fonts/BloggerSans-Bold.ttf",
|
||||
"range": "0x20-0x7e, 0x410-0x44f, 0xB0"
|
||||
}
|
||||
],
|
||||
"bpp": 1,
|
||||
"size": 34,
|
||||
"format": "bin",
|
||||
"target_path": "/fonts/"
|
||||
}
|
||||
}
|
||||
|
|
BIN
src/resources/fonts/BloggerSans-Bold.ttf
Normal file
BIN
src/resources/fonts/BloggerSans-Bold.ttf
Normal file
Binary file not shown.
50
src/resources/resources.json
Normal file
50
src/resources/resources.json
Normal file
|
@ -0,0 +1,50 @@
|
|||
{
|
||||
"resources": [
|
||||
{
|
||||
"filename": "teko.bin",
|
||||
"path": "/fonts/teko.bin"
|
||||
},
|
||||
{
|
||||
"filename": "7segments_40.bin",
|
||||
"path": "/fonts/7segments_40.bin"
|
||||
},
|
||||
{
|
||||
"filename": "lv_font_dots_40.bin",
|
||||
"path": "/fonts/lv_font_dots_40.bin"
|
||||
},
|
||||
{
|
||||
"filename": "7segments_115.bin",
|
||||
"path": "/fonts/7segments_115.bin"
|
||||
},
|
||||
{
|
||||
"filename": "bebas.bin",
|
||||
"path": "/fonts/bebas.bin"
|
||||
},
|
||||
{
|
||||
"filename": "rounded_small.bin",
|
||||
"path": "/fonts/rounded_small.bin"
|
||||
},
|
||||
{
|
||||
"filename": "rounded_large.bin",
|
||||
"path": "/fonts/rounded_large.bin"
|
||||
},
|
||||
{
|
||||
"filename": "pine_small.bin",
|
||||
"path": "/images/pine_small.bin"
|
||||
},
|
||||
{
|
||||
"filename": "navigation1.bin",
|
||||
"path": "/images/navigation1.bin"
|
||||
},
|
||||
{
|
||||
"filename": "navigation0.bin",
|
||||
"path": "/images/navigation0.bin"
|
||||
}
|
||||
],
|
||||
"obsolete_files": [
|
||||
{
|
||||
"path": "/example-of-obsolete-file.bin",
|
||||
"since": "1.11.0"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -216,7 +216,7 @@ void SystemTask::Work() {
|
|||
GoToSleep();
|
||||
break;
|
||||
case Messages::OnNewTime:
|
||||
if (alarmController.State() == Controllers::AlarmController::AlarmState::Set) {
|
||||
if (alarmController.IsEnabled()) {
|
||||
alarmController.ScheduleAlarm();
|
||||
}
|
||||
break;
|
||||
|
@ -317,8 +317,7 @@ void SystemTask::Work() {
|
|||
case Messages::OnNewHour:
|
||||
using Pinetime::Controllers::AlarmController;
|
||||
if (settingsController.GetNotificationStatus() != Controllers::Settings::Notification::Sleep &&
|
||||
settingsController.GetChimeOption() == Controllers::Settings::ChimesOption::Hours &&
|
||||
alarmController.State() != AlarmController::AlarmState::Alerting) {
|
||||
settingsController.GetChimeOption() == Controllers::Settings::ChimesOption::Hours && !alarmController.IsAlerting()) {
|
||||
GoToRunning();
|
||||
displayApp.PushMessage(Pinetime::Applications::Display::Messages::Chime);
|
||||
}
|
||||
|
@ -326,8 +325,7 @@ void SystemTask::Work() {
|
|||
case Messages::OnNewHalfHour:
|
||||
using Pinetime::Controllers::AlarmController;
|
||||
if (settingsController.GetNotificationStatus() != Controllers::Settings::Notification::Sleep &&
|
||||
settingsController.GetChimeOption() == Controllers::Settings::ChimesOption::HalfHours &&
|
||||
alarmController.State() != AlarmController::AlarmState::Alerting) {
|
||||
settingsController.GetChimeOption() == Controllers::Settings::ChimesOption::HalfHours && !alarmController.IsAlerting()) {
|
||||
GoToRunning();
|
||||
displayApp.PushMessage(Pinetime::Applications::Display::Messages::Chime);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue