Merge branch 'develop' into notifications-as-text
This commit is contained in:
commit
452dd12eff
|
@ -16,6 +16,7 @@ Fast open-source firmware for the [PineTime smartwatch](https://www.pine64.org/p
|
||||||
- [AmazFish](https://openrepos.net/content/piggz/amazfish/) (SailfishOS)
|
- [AmazFish](https://openrepos.net/content/piggz/amazfish/) (SailfishOS)
|
||||||
- [Siglo](https://github.com/alexr4535/siglo) (Linux)
|
- [Siglo](https://github.com/alexr4535/siglo) (Linux)
|
||||||
- [InfiniLink](https://github.com/xan-m/InfiniLink) **[Experimental]** (iOS)
|
- [InfiniLink](https://github.com/xan-m/InfiniLink) **[Experimental]** (iOS)
|
||||||
|
- [ITD](https://gitea.arsenm.dev/Arsen6331/itd) (Linux)
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ void Settings::LoadSettingsFromFile() {
|
||||||
SettingsData bufferSettings;
|
SettingsData bufferSettings;
|
||||||
lfs_file_t settingsFile;
|
lfs_file_t settingsFile;
|
||||||
|
|
||||||
if ( fs.FileOpen(&settingsFile, "/settings.dat", LFS_O_RDWR | LFS_O_CREAT) != LFS_ERR_OK) {
|
if ( fs.FileOpen(&settingsFile, "/settings.dat", LFS_O_RDONLY) != LFS_ERR_OK) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fs.FileRead(&settingsFile, reinterpret_cast<uint8_t*>(&bufferSettings), sizeof(settings));
|
fs.FileRead(&settingsFile, reinterpret_cast<uint8_t*>(&bufferSettings), sizeof(settings));
|
||||||
|
@ -39,7 +39,7 @@ void Settings::LoadSettingsFromFile() {
|
||||||
void Settings::SaveSettingsToFile() {
|
void Settings::SaveSettingsToFile() {
|
||||||
lfs_file_t settingsFile;
|
lfs_file_t settingsFile;
|
||||||
|
|
||||||
if ( fs.FileOpen(&settingsFile, "/settings.dat", LFS_O_RDWR | LFS_O_CREAT) != LFS_ERR_OK) {
|
if ( fs.FileOpen(&settingsFile, "/settings.dat", LFS_O_WRONLY | LFS_O_CREAT) != LFS_ERR_OK) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fs.FileWrite(&settingsFile, reinterpret_cast<uint8_t*>(&settings), sizeof(settings));
|
fs.FileWrite(&settingsFile, reinterpret_cast<uint8_t*>(&settings), sizeof(settings));
|
||||||
|
|
|
@ -31,6 +31,22 @@ Add new symbols:
|
||||||
static constexpr const char* newSymbol = "\xEF\x86\x85";
|
static constexpr const char* newSymbol = "\xEF\x86\x85";
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Then fix an error that happens during the font conversion (the inner dot of the 'zero' symbol sticks to the boundary): edit `src/displayapp/fonts/jetbrains_mono_bold_20.c` and replace:
|
||||||
|
|
||||||
|
/* U+0030 "0" */
|
||||||
|
0x3f, 0x1f, 0xef, 0x3f, 0x87, 0xe1, 0xf8, 0x7f,
|
||||||
|
0xdf, 0xf7, 0xe1, 0xf8, 0x7e, 0x1f, 0xcf, 0x7f,
|
||||||
|
0x8f, 0xc0,
|
||||||
|
|
||||||
|
with
|
||||||
|
|
||||||
|
/* U+0030 "0" */
|
||||||
|
0x3f, 0x1f, 0xef, 0x3f, 0x87, 0xe1, 0xf8, 0x7e,
|
||||||
|
0xdf, 0xb7, 0xe1, 0xf8, 0x7e, 0x1f, 0xcf, 0x7f,
|
||||||
|
0x8f, 0xc0,
|
||||||
|
|
||||||
|
(there are two changes: 7f -> 7e and f7 -> b7)
|
||||||
|
|
||||||
## Simple method to generate a font
|
## Simple method to generate a font
|
||||||
|
|
||||||
If you want to generate a basic font containing only numbers and letters, you can use the above settings but instead of specifying a range, simply list the characters you need in the Symbols field and leave the range blank. This is the approach used for the PineTimeStyle watchface.
|
If you want to generate a basic font containing only numbers and letters, you can use the above settings but instead of specifying a range, simply list the characters you need in the Symbols field and leave the range blank. This is the approach used for the PineTimeStyle watchface.
|
||||||
|
|
|
@ -88,8 +88,8 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
|
||||||
0xe, 0x3, 0x80, 0xc0, 0x70, 0x18, 0xe, 0x0,
|
0xe, 0x3, 0x80, 0xc0, 0x70, 0x18, 0xe, 0x0,
|
||||||
|
|
||||||
/* U+0030 "0" */
|
/* U+0030 "0" */
|
||||||
0x3f, 0x1f, 0xef, 0x3f, 0x87, 0xe1, 0xf8, 0x7f,
|
0x3f, 0x1f, 0xef, 0x3f, 0x87, 0xe1, 0xf8, 0x7e,
|
||||||
0xdf, 0xf7, 0xe1, 0xf8, 0x7e, 0x1f, 0xcf, 0x7f,
|
0xdf, 0xb7, 0xe1, 0xf8, 0x7e, 0x1f, 0xcf, 0x7f,
|
||||||
0x8f, 0xc0,
|
0x8f, 0xc0,
|
||||||
|
|
||||||
/* U+0031 "1" */
|
/* U+0031 "1" */
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include "displayapp/screens/Screen.h"
|
#include "displayapp/screens/Screen.h"
|
||||||
#include <bits/unique_ptr.h>
|
|
||||||
#include "systemtask/SystemTask.h"
|
#include "systemtask/SystemTask.h"
|
||||||
#include <lvgl/src/lv_core/lv_style.h>
|
#include <lvgl/src/lv_core/lv_style.h>
|
||||||
#include <lvgl/src/lv_core/lv_obj.h>
|
#include <lvgl/src/lv_core/lv_obj.h>
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include "displayapp/screens/Screen.h"
|
#include "displayapp/screens/Screen.h"
|
||||||
#include <bits/unique_ptr.h>
|
|
||||||
#include <lvgl/src/lv_core/lv_style.h>
|
#include <lvgl/src/lv_core/lv_style.h>
|
||||||
#include <lvgl/src/lv_core/lv_obj.h>
|
#include <lvgl/src/lv_core/lv_obj.h>
|
||||||
#include <components/motion/MotionController.h>
|
#include <components/motion/MotionController.h>
|
||||||
|
|
|
@ -198,15 +198,18 @@ Notifications::NotificationItem::NotificationItem(const char* title,
|
||||||
|
|
||||||
lv_obj_t* alert_type = lv_label_create(lv_scr_act(), nullptr);
|
lv_obj_t* alert_type = lv_label_create(lv_scr_act(), nullptr);
|
||||||
lv_obj_set_style_local_text_color(alert_type, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x888888));
|
lv_obj_set_style_local_text_color(alert_type, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x888888));
|
||||||
if (title == nullptr)
|
if(title == nullptr) {
|
||||||
title = "Notification";
|
lv_label_set_text_static(alert_type, "Notification");
|
||||||
char* pchar;
|
} else {
|
||||||
pchar = strchr(title, '\n');
|
// copy title to label and replace newlines with spaces
|
||||||
while (pchar != nullptr) {
|
lv_label_set_text(alert_type, title);
|
||||||
*pchar = ' ';
|
char *pchar = strchr(lv_label_get_text(alert_type), '\n');
|
||||||
pchar = strchr(pchar + 1, '\n');
|
while (pchar != nullptr) {
|
||||||
|
*pchar = ' ';
|
||||||
|
pchar = strchr(pchar + 1, '\n');
|
||||||
|
}
|
||||||
|
lv_label_refr_text(alert_type);
|
||||||
}
|
}
|
||||||
lv_label_set_text(alert_type, title);
|
|
||||||
lv_label_set_long_mode(alert_type, LV_LABEL_LONG_SROLL_CIRC);
|
lv_label_set_long_mode(alert_type, LV_LABEL_LONG_SROLL_CIRC);
|
||||||
lv_obj_set_width(alert_type, 180);
|
lv_obj_set_width(alert_type, 180);
|
||||||
lv_obj_align(alert_type, NULL, LV_ALIGN_IN_TOP_LEFT, 0, 16);
|
lv_obj_align(alert_type, NULL, LV_ALIGN_IN_TOP_LEFT, 0, 16);
|
||||||
|
|
|
@ -62,10 +62,6 @@ namespace Pinetime {
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct NotificationData {
|
|
||||||
const char* title;
|
|
||||||
const char* text;
|
|
||||||
};
|
|
||||||
Pinetime::Controllers::NotificationManager& notificationManager;
|
Pinetime::Controllers::NotificationManager& notificationManager;
|
||||||
Pinetime::Controllers::AlertNotificationService& alertNotificationService;
|
Pinetime::Controllers::AlertNotificationService& alertNotificationService;
|
||||||
Pinetime::Controllers::MotorController& motorController;
|
Pinetime::Controllers::MotorController& motorController;
|
||||||
|
|
|
@ -57,7 +57,6 @@ WatchFaceAnalog::WatchFaceAnalog(Pinetime::Applications::DisplayApp* app,
|
||||||
bleController {bleController},
|
bleController {bleController},
|
||||||
notificationManager {notificationManager},
|
notificationManager {notificationManager},
|
||||||
settingsController {settingsController} {
|
settingsController {settingsController} {
|
||||||
settingsController.SetClockFace(1);
|
|
||||||
|
|
||||||
sHour = 99;
|
sHour = 99;
|
||||||
sMinute = 99;
|
sMinute = 99;
|
||||||
|
|
|
@ -32,7 +32,6 @@ WatchFaceDigital::WatchFaceDigital(DisplayApp* app,
|
||||||
settingsController {settingsController},
|
settingsController {settingsController},
|
||||||
heartRateController {heartRateController},
|
heartRateController {heartRateController},
|
||||||
motionController {motionController} {
|
motionController {motionController} {
|
||||||
settingsController.SetClockFace(0);
|
|
||||||
|
|
||||||
batteryIcon = lv_label_create(lv_scr_act(), nullptr);
|
batteryIcon = lv_label_create(lv_scr_act(), nullptr);
|
||||||
lv_label_set_text_static(batteryIcon, Symbols::batteryFull);
|
lv_label_set_text_static(batteryIcon, Symbols::batteryFull);
|
||||||
|
|
|
@ -32,14 +32,6 @@ WatchFaceTerminal::WatchFaceTerminal(DisplayApp* app,
|
||||||
motionController {motionController} {
|
motionController {motionController} {
|
||||||
settingsController.SetClockFace(3);
|
settingsController.SetClockFace(3);
|
||||||
|
|
||||||
batteryIcon = lv_label_create(lv_scr_act(), nullptr);
|
|
||||||
lv_label_set_text(batteryIcon, Symbols::batteryFull);
|
|
||||||
lv_obj_align(batteryIcon, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, -5, 2);
|
|
||||||
|
|
||||||
batteryPlug = lv_label_create(lv_scr_act(), nullptr);
|
|
||||||
lv_label_set_text(batteryPlug, Symbols::plug);
|
|
||||||
lv_obj_align(batteryPlug, batteryIcon, LV_ALIGN_OUT_LEFT_MID, -5, 0);
|
|
||||||
|
|
||||||
batteryValue = lv_label_create(lv_scr_act(), nullptr);
|
batteryValue = lv_label_create(lv_scr_act(), nullptr);
|
||||||
lv_label_set_recolor(batteryValue, true);
|
lv_label_set_recolor(batteryValue, true);
|
||||||
lv_obj_align(batteryValue, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, -20);
|
lv_obj_align(batteryValue, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, -20);
|
||||||
|
@ -58,11 +50,11 @@ WatchFaceTerminal::WatchFaceTerminal(DisplayApp* app,
|
||||||
|
|
||||||
label_prompt_1 = lv_label_create(lv_scr_act(), nullptr);
|
label_prompt_1 = lv_label_create(lv_scr_act(), nullptr);
|
||||||
lv_obj_align(label_prompt_1, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, -80);
|
lv_obj_align(label_prompt_1, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, -80);
|
||||||
lv_label_set_text(label_prompt_1, "user@watch:~ $ now");
|
lv_label_set_text_static(label_prompt_1, "user@watch:~ $ now");
|
||||||
|
|
||||||
label_prompt_2 = lv_label_create(lv_scr_act(), nullptr);
|
label_prompt_2 = lv_label_create(lv_scr_act(), nullptr);
|
||||||
lv_obj_align(label_prompt_2, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, 60);
|
lv_obj_align(label_prompt_2, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, 60);
|
||||||
lv_label_set_text(label_prompt_2, "user@watch:~ $");
|
lv_label_set_text_static(label_prompt_2, "user@watch:~ $");
|
||||||
|
|
||||||
label_time = lv_label_create(lv_scr_act(), nullptr);
|
label_time = lv_label_create(lv_scr_act(), nullptr);
|
||||||
lv_label_set_recolor(label_time, true);
|
lv_label_set_recolor(label_time, true);
|
||||||
|
@ -73,16 +65,14 @@ WatchFaceTerminal::WatchFaceTerminal(DisplayApp* app,
|
||||||
lv_label_set_long_mode(backgroundLabel, LV_LABEL_LONG_CROP);
|
lv_label_set_long_mode(backgroundLabel, LV_LABEL_LONG_CROP);
|
||||||
lv_obj_set_size(backgroundLabel, 240, 240);
|
lv_obj_set_size(backgroundLabel, 240, 240);
|
||||||
lv_obj_set_pos(backgroundLabel, 0, 0);
|
lv_obj_set_pos(backgroundLabel, 0, 0);
|
||||||
lv_label_set_text(backgroundLabel, "");
|
lv_label_set_text_static(backgroundLabel, "");
|
||||||
|
|
||||||
heartbeatValue = lv_label_create(lv_scr_act(), nullptr);
|
heartbeatValue = lv_label_create(lv_scr_act(), nullptr);
|
||||||
lv_label_set_recolor(heartbeatValue, true);
|
lv_label_set_recolor(heartbeatValue, true);
|
||||||
lv_label_set_text(heartbeatValue, "[L_HR]#ee3311 0 bpm#");
|
|
||||||
lv_obj_align(heartbeatValue, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, 20);
|
lv_obj_align(heartbeatValue, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, 20);
|
||||||
|
|
||||||
stepValue = lv_label_create(lv_scr_act(), nullptr);
|
stepValue = lv_label_create(lv_scr_act(), nullptr);
|
||||||
lv_label_set_recolor(stepValue, true);
|
lv_label_set_recolor(stepValue, true);
|
||||||
lv_label_set_text(stepValue, "[STEP]#ee3377 0 steps#");
|
|
||||||
lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, 0);
|
lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, 0);
|
||||||
|
|
||||||
taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this);
|
taskRefresh = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this);
|
||||||
|
@ -96,20 +86,12 @@ WatchFaceTerminal::~WatchFaceTerminal() {
|
||||||
|
|
||||||
void WatchFaceTerminal::Refresh() {
|
void WatchFaceTerminal::Refresh() {
|
||||||
powerPresent = batteryController.IsPowerPresent();
|
powerPresent = batteryController.IsPowerPresent();
|
||||||
if (powerPresent.IsUpdated()) {
|
|
||||||
lv_label_set_text_static(batteryPlug, BatteryIcon::GetPlugIcon(powerPresent.Get()));
|
|
||||||
}
|
|
||||||
|
|
||||||
batteryPercentRemaining = batteryController.PercentRemaining();
|
batteryPercentRemaining = batteryController.PercentRemaining();
|
||||||
if (batteryPercentRemaining.IsUpdated()) {
|
if (batteryPercentRemaining.IsUpdated() || powerPresent.IsUpdated()) {
|
||||||
auto batteryPercent = batteryPercentRemaining.Get();
|
lv_label_set_text_fmt(batteryValue, "[BATT]#387b54 %d%%", batteryPercentRemaining.Get());
|
||||||
if (batteryPercent == 100) {
|
if (batteryController.IsPowerPresent()) {
|
||||||
lv_obj_set_style_local_text_color(batteryIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GREEN);
|
lv_label_ins_text(batteryValue, LV_LABEL_POS_LAST, " Charging");
|
||||||
} else {
|
|
||||||
lv_obj_set_style_local_text_color(batteryIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE);
|
|
||||||
}
|
}
|
||||||
lv_label_set_text(batteryIcon, BatteryIcon::GetBatteryIcon(batteryPercent));
|
|
||||||
lv_label_set_text_fmt(batteryValue, "[BATT]#387b54 %d%\%#", batteryPercent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bleState = bleController.IsConnected();
|
bleState = bleController.IsConnected();
|
||||||
|
|
|
@ -60,8 +60,6 @@ namespace Pinetime {
|
||||||
lv_obj_t* label_prompt_1;
|
lv_obj_t* label_prompt_1;
|
||||||
lv_obj_t* label_prompt_2;
|
lv_obj_t* label_prompt_2;
|
||||||
lv_obj_t* backgroundLabel;
|
lv_obj_t* backgroundLabel;
|
||||||
lv_obj_t* batteryIcon;
|
|
||||||
lv_obj_t* batteryPlug;
|
|
||||||
lv_obj_t* batteryValue;
|
lv_obj_t* batteryValue;
|
||||||
lv_obj_t* heartbeatValue;
|
lv_obj_t* heartbeatValue;
|
||||||
lv_obj_t* stepValue;
|
lv_obj_t* stepValue;
|
||||||
|
|
|
@ -64,7 +64,7 @@ std::unique_ptr<Screen> Settings::CreateScreen3() {
|
||||||
{Symbols::clock, "Chimes", Apps::SettingChimes},
|
{Symbols::clock, "Chimes", Apps::SettingChimes},
|
||||||
{Symbols::tachometer, "Shake Calib.", Apps::SettingShakeThreshold},
|
{Symbols::tachometer, "Shake Calib.", Apps::SettingShakeThreshold},
|
||||||
{Symbols::check, "Firmware", Apps::FirmwareValidation},
|
{Symbols::check, "Firmware", Apps::FirmwareValidation},
|
||||||
{Symbols::list, "Airplane mode", Apps::SettingAirplaneMode}
|
{Symbols::airplane, "Airplane mode", Apps::SettingAirplaneMode}
|
||||||
}};
|
}};
|
||||||
|
|
||||||
return std::make_unique<Screens::List>(2, 4, app, settingsController, applications);
|
return std::make_unique<Screens::List>(2, 4, app, settingsController, applications);
|
||||||
|
|
Loading…
Reference in a new issue