Compare commits

...

12 commits

Author SHA1 Message Date
liamcharger 6bdba5cd07
Merge f9add3637e into a2356f2f4a 2024-10-01 22:39:26 +02:00
NeroBurner a2356f2f4a
MusicService: add missing includes for TickType_t and xTaskGetTickCount (#2130)
Some checks failed
CI / build-firmware (push) Successful in 10m55s
CI / build-simulator (push) Failing after 3s
CI / get-base-ref-size (push) Has been skipped
CI / Compare build size (push) Has been skipped
Add `FreeRTOS.h` include for the directly used data type `TickType_t` in the header
and the function `xTaskGetTickCount` from FreeRTOS's `task.h`
2024-09-29 21:10:32 +02:00
NeroBurner 3db4e012ce
Remove unused pointer to DisplayApp member variables (#2125)
Some checks failed
CI / build-firmware (push) Successful in 10m10s
CI / build-simulator (push) Failing after 3s
CI / get-base-ref-size (push) Has been skipped
CI / Compare build size (push) Has been skipped
In the screens that use `DisplayApp *app` and pass it to a child item,
or use the reference just in the constructor. Afterwards the `app`
member is not used. So remove it from the private member variables.

Completely remove `app` parameter from `SettingDisplay` constructor as
it is unused.
2024-09-29 19:39:14 +02:00
NeroBurner a0cd439efc
Alarm persist to flash (#1367)
Some checks failed
CI / build-firmware (push) Successful in 13m37s
CI / build-simulator (push) Failing after 4s
CI / get-base-ref-size (push) Has been skipped
CI / Compare build size (push) Has been skipped
* AlarmController: Add saving alarm time to file

Save the set alarm time to the SPI NOR flash, so it does not reset to
the default value when the watch resets, e.g. due to watchdog timeout
or reflashing of a new version of InfiniTime.

Just like the `Settings.h` `LoadSettingsFromFile()` the previous alarm
at boot (if available) and `SaveSettingsToFile()` the current alarm when
the `Alarm.h` screen is closed (only if the settings have changed).

The alarm-settings file is stored in `.system/alarm.dat`. The `.system`
folder is created if it doesn't yet exist.

Fixes: https://github.com/InfiniTimeOrg/InfiniTime/issues/1330

* alarmController: close .system dir after usage

Close the `lfs_dir` object for the `.system` dir after usage. Otherwise
on the second changed alarm the system will lockup because the `.system`
dir is already open and was never closed.

---------

Co-authored-by: Galdor Takacs <g@ldor.de>
2024-09-28 08:14:08 +02:00
liamcharger f9add3637e
Merge branch 'main' into numeral-watch-face 2024-04-18 15:56:30 -04:00
liamcharger 2d47679212 Minor improvements 2024-04-06 07:15:17 +10:30
liamcharger e2e063cb37 Fix 24H display issues 2024-03-31 13:18:30 +10:30
liamcharger 3905b3bafd Minor improvements to notification icon display 2024-03-31 12:06:41 +10:30
liamcharger e25ca95c47 Minor improvements 2024-03-31 07:23:25 +10:30
liamcharger 206c88c0da Fix workflow error 2024-03-31 05:12:35 +10:30
liamcharger 3915d3a344 Minor improvements 2024-03-31 04:57:11 +10:30
liamcharger f6731c1a5a Initial commit 2024-03-31 04:52:29 +10:30
25 changed files with 459 additions and 62 deletions

View file

@ -426,6 +426,7 @@ list(APPEND SOURCE_FILES
displayapp/screens/WatchFaceTerminal.cpp
displayapp/screens/WatchFacePineTimeStyle.cpp
displayapp/screens/WatchFaceCasioStyleG7710.cpp
displayapp/screens/WatchFaceNumerals.cpp
##

View file

@ -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);
}

View file

@ -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;
};
}
}

View file

@ -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

View file

@ -25,6 +25,7 @@
#include <host/ble_uuid.h>
#undef max
#undef min
#include <FreeRTOS.h>
namespace Pinetime {
namespace Controllers {

View file

@ -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);

View file

@ -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 {

View file

@ -52,6 +52,7 @@ namespace Pinetime {
Terminal,
Infineat,
CasioStyleG7710,
Numerals,
};
template <Apps>

View file

@ -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()

View file

@ -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;

View file

@ -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},

View file

@ -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;

View 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;
}

View 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);
}
};
}
}

View file

@ -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);

View file

@ -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;

View file

@ -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,

View file

@ -20,7 +20,6 @@ namespace Pinetime {
void Quit();
private:
DisplayApp* app;
Controllers::DateTime& dateTimeController;
Controllers::Settings& settingsController;

View file

@ -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} {

View file

@ -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;

View file

@ -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 {};

View file

@ -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/"
}
}

Binary file not shown.

View 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"
}
]
}

View file

@ -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);
}