Merge branch 'evergreen22-airplane-mode' into develop

This commit is contained in:
Jean-François Milants 2022-02-20 15:41:06 +01:00
commit 0e2b27d792
26 changed files with 370 additions and 107 deletions

View File

@ -449,6 +449,7 @@ list(APPEND SOURCE_FILES
displayapp/screens/settings/SettingSetTime.cpp
displayapp/screens/settings/SettingChimes.cpp
displayapp/screens/settings/SettingShakeThreshold.cpp
displayapp/screens/settings/SettingAirplaneMode.cpp
## Watch faces
displayapp/icons/bg_clock.c

View File

@ -2,6 +2,10 @@
using namespace Pinetime::Controllers;
bool Ble::IsConnected() const {
return isConnected;
}
void Ble::Connect() {
isConnected = true;
}
@ -10,6 +14,18 @@ void Ble::Disconnect() {
isConnected = false;
}
bool Ble::IsRadioEnabled() const {
return isRadioEnabled;
}
void Ble::EnableRadio() {
isRadioEnabled = true;
}
void Ble::DisableRadio() {
isRadioEnabled = false;
}
void Ble::StartFirmwareUpdate() {
isFirmwareUpdating = true;
}

View File

@ -12,12 +12,14 @@ namespace Pinetime {
enum class AddressTypes { Public, Random, RPA_Public, RPA_Random };
Ble() = default;
bool IsConnected() const {
return isConnected;
}
bool IsConnected() const;
void Connect();
void Disconnect();
bool IsRadioEnabled() const;
void EnableRadio();
void DisableRadio();
void StartFirmwareUpdate();
void StopFirmwareUpdate();
void FirmwareUpdateTotalBytes(uint32_t totalBytes);
@ -57,6 +59,7 @@ namespace Pinetime {
private:
bool isConnected = false;
bool isRadioEnabled = true;
bool isFirmwareUpdating = false;
uint32_t firmwareUpdateTotalBytes = 0;
uint32_t firmwareUpdateCurrentBytes = 0;

View File

@ -23,14 +23,14 @@
using namespace Pinetime::Controllers;
NimbleController::NimbleController(Pinetime::System::SystemTask& systemTask,
Pinetime::Controllers::Ble& bleController,
Ble& bleController,
DateTime& dateTimeController,
Pinetime::Controllers::NotificationManager& notificationManager,
Controllers::Battery& batteryController,
NotificationManager& notificationManager,
Battery& batteryController,
Pinetime::Drivers::SpiNorFlash& spiNorFlash,
Controllers::HeartRateController& heartRateController,
Controllers::MotionController& motionController,
Controllers::FS& fs)
HeartRateController& heartRateController,
MotionController& motionController,
FS& fs)
: systemTask {systemTask},
bleController {bleController},
dateTimeController {dateTimeController},
@ -184,7 +184,9 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) {
case BLE_GAP_EVENT_ADV_COMPLETE:
NRF_LOG_INFO("Advertising event : BLE_GAP_EVENT_ADV_COMPLETE");
NRF_LOG_INFO("reason=%d; status=%0X", event->adv_complete.reason, event->connect.status);
StartAdvertising();
if (bleController.IsRadioEnabled() && !bleController.IsConnected()) {
StartAdvertising();
}
break;
case BLE_GAP_EVENT_CONNECT:
@ -220,9 +222,11 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) {
currentTimeClient.Reset();
alertNotificationClient.Reset();
connectionHandle = BLE_HS_CONN_HANDLE_NONE;
bleController.Disconnect();
fastAdvCount = 0;
StartAdvertising();
if(bleController.IsConnected()) {
bleController.Disconnect();
fastAdvCount = 0;
StartAdvertising();
}
break;
case BLE_GAP_EVENT_CONN_UPDATE:
@ -397,6 +401,23 @@ void NimbleController::NotifyBatteryLevel(uint8_t level) {
}
}
void NimbleController::EnableRadio() {
bleController.EnableRadio();
bleController.Disconnect();
fastAdvCount = 0;
StartAdvertising();
}
void NimbleController::DisableRadio() {
bleController.DisableRadio();
if (bleController.IsConnected()) {
ble_gap_terminate(connectionHandle, BLE_ERR_REM_USER_CONN_TERM);
bleController.Disconnect();
} else {
ble_gap_adv_stop();
}
}
void NimbleController::PersistBond(struct ble_gap_conn_desc& desc) {
union ble_store_key key;
union ble_store_value our_sec, peer_sec, peer_cccd_set[MYNEWT_VAL(BLE_STORE_MAX_CCCDS)] = {0};

View File

@ -14,6 +14,7 @@
#include "components/ble/CurrentTimeService.h"
#include "components/ble/DeviceInformationService.h"
#include "components/ble/DfuService.h"
#include "components/ble/FSService.h"
#include "components/ble/HeartRateService.h"
#include "components/ble/ImmediateAlertService.h"
#include "components/ble/MusicService.h"
@ -22,7 +23,6 @@
#include "components/ble/MotionService.h"
#include "components/ble/weather/WeatherService.h"
#include "components/fs/FS.h"
#include "components/ble/FSService.h"
namespace Pinetime {
namespace Drivers {
@ -42,27 +42,17 @@ namespace Pinetime {
public:
NimbleController(Pinetime::System::SystemTask& systemTask,
Pinetime::Controllers::Ble& bleController,
Ble& bleController,
DateTime& dateTimeController,
Pinetime::Controllers::NotificationManager& notificationManager,
Controllers::Battery& batteryController,
NotificationManager& notificationManager,
Battery& batteryController,
Pinetime::Drivers::SpiNorFlash& spiNorFlash,
Controllers::HeartRateController& heartRateController,
Controllers::MotionController& motionController,
Pinetime::Controllers::FS& fs);
HeartRateController& heartRateController,
MotionController& motionController,
FS& fs);
void Init();
void StartAdvertising();
int OnGAPEvent(ble_gap_event* event);
int OnDiscoveryEvent(uint16_t i, const ble_gatt_error* pError, const ble_gatt_svc* pSvc);
int OnCTSCharacteristicDiscoveryEvent(uint16_t connectionHandle, const ble_gatt_error* error, const ble_gatt_chr* characteristic);
int OnANSCharacteristicDiscoveryEvent(uint16_t connectionHandle, const ble_gatt_error* error, const ble_gatt_chr* characteristic);
int OnCurrentTimeReadResult(uint16_t connectionHandle, const ble_gatt_error* error, ble_gatt_attr* attribute);
int OnANSDescriptorDiscoveryEventCallback(uint16_t connectionHandle,
const ble_gatt_error* error,
uint16_t characteristicValueHandle,
const ble_gatt_dsc* descriptor);
void StartDiscovery();
Pinetime::Controllers::MusicService& music() {
@ -83,7 +73,10 @@ namespace Pinetime {
void RestartFastAdv() {
fastAdvCount = 0;
}
};
void EnableRadio();
void DisableRadio();
private:
void PersistBond(struct ble_gap_conn_desc& desc);
@ -91,12 +84,12 @@ namespace Pinetime {
static constexpr const char* deviceName = "InfiniTime";
Pinetime::System::SystemTask& systemTask;
Pinetime::Controllers::Ble& bleController;
Ble& bleController;
DateTime& dateTimeController;
Pinetime::Controllers::NotificationManager& notificationManager;
NotificationManager& notificationManager;
Pinetime::Drivers::SpiNorFlash& spiNorFlash;
Pinetime::Controllers::FS& fs;
Pinetime::Controllers::DfuService dfuService;
FS& fs;
DfuService dfuService;
DeviceInformationService deviceInformationService;
CurrentTimeClient currentTimeClient;

View File

@ -18,7 +18,23 @@ namespace Pinetime {
Shake = 3,
};
enum class Colors : uint8_t {
White, Silver, Gray, Black, Red, Maroon, Yellow, Olive, Lime, Green, Cyan, Teal, Blue, Navy, Magenta, Purple, Orange
White,
Silver,
Gray,
Black,
Red,
Maroon,
Yellow,
Olive,
Lime,
Green,
Cyan,
Teal,
Blue,
Navy,
Magenta,
Purple,
Orange
};
struct PineTimeStyle {
Colors ColorTime = Colors::Teal;
@ -170,18 +186,29 @@ namespace Pinetime {
}
settings.brightLevel = level;
};
Controllers::BrightnessController::Levels GetBrightness() const {
return settings.brightLevel;
};
void SetStepsGoal( uint32_t goal ) {
if ( goal != settings.stepsGoal ) {
void SetStepsGoal(uint32_t goal) {
if (goal != settings.stepsGoal) {
settingsChanged = true;
}
settings.stepsGoal = goal;
};
uint32_t GetStepsGoal() const { return settings.stepsGoal; };
uint32_t GetStepsGoal() const {
return settings.stepsGoal;
};
void SetBleRadioEnabled(bool enabled) {
bleRadioEnabled = enabled;
};
bool GetBleRadioEnabled() const {
return bleRadioEnabled;
};
private:
Pinetime::Controllers::FS& fs;
@ -210,6 +237,10 @@ namespace Pinetime {
uint8_t appMenu = 0;
uint8_t settingsMenu = 0;
/* airplaneMode is intentionally not saved with the other watch settings and initialized
* to off (false) on every boot because we always want ble to be enabled on startup
*/
bool bleRadioEnabled = true;
void LoadSettingsFromFile();
void SaveSettingsToFile();

View File

@ -38,6 +38,7 @@ namespace Pinetime {
SettingSetTime,
SettingChimes,
SettingShakeThreshold,
SettingAirplaneMode,
Error
};
}

View File

@ -49,6 +49,7 @@
#include "displayapp/screens/settings/SettingSetTime.h"
#include "displayapp/screens/settings/SettingChimes.h"
#include "displayapp/screens/settings/SettingShakeThreshold.h"
#include "displayapp/screens/settings/SettingAirplaneMode.h"
#include "libs/lv_conf.h"
@ -292,6 +293,9 @@ void DisplayApp::Refresh() {
case Messages::BleFirmwareUpdateStarted:
LoadApp(Apps::FirmwareUpdate, DisplayApp::FullRefreshDirections::Down);
break;
case Messages::BleRadioEnableToggle:
PushMessageToSystemTask(System::Messages::BleRadioEnableToggle);
break;
case Messages::UpdateDateTime:
// Added to remove warning
// What should happen here?
@ -430,6 +434,10 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction)
currentScreen = std::make_unique<Screens::SettingShakeThreshold>(this, settingsController, motionController, *systemTask);
ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown);
break;
case Apps::SettingAirplaneMode:
currentScreen = std::make_unique<Screens::SettingAirplaneMode>(this, settingsController);
ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown);
break;
case Apps::BatteryInfo:
currentScreen = std::make_unique<Screens::BatteryInfo>(this, batteryController);
ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown);

View File

@ -21,7 +21,8 @@ namespace Pinetime {
RestoreBrightness,
ShowPairingKey,
AlarmTriggered,
Clock
Clock,
BleRadioEnableToggle
};
}
}

View File

@ -13,7 +13,7 @@
* Do not enable font compression and horizontal subpixel hinting
* Load the file `JetBrainsMono-Bold.tff` (use the file in this repo to ensure the version matches) and specify the following range : `0x20-0x7f, 0x410-0x44f`
* Add a 2nd font, load the file `FontAwesome5-Solid+Brands+Regular.woff` and specify the following
range : `0xf293, 0xf294, 0xf244, 0xf240, 0xf242, 0xf243, 0xf241, 0xf54b, 0xf21e, 0xf1e6, 0xf54b, 0xf017, 0xf129, 0xf03a, 0xf185, 0xf560, 0xf001, 0xf3fd, 0xf069, 0xf1fc, 0xf45d, 0xf59f, 0xf5a0, 0xf029, 0xf027, 0xf028, 0xf6a9, 0xf04b, 0xf04c, 0xf048, 0xf051, 0xf095, 0xf3dd, 0xf04d, 0xf2f2, 0xf024, 0xf252, 0xf569, 0xf201, 0xf06e, 0xf015`
range : `0xf293, 0xf294, 0xf244, 0xf240, 0xf242, 0xf243, 0xf241, 0xf54b, 0xf21e, 0xf1e6, 0xf54b, 0xf017, 0xf129, 0xf03a, 0xf185, 0xf560, 0xf001, 0xf3fd, 0xf069, 0xf1fc, 0xf45d, 0xf59f, 0xf5a0, 0xf029, 0xf027, 0xf028, 0xf6a9, 0xf04b, 0xf04c, 0xf048, 0xf051, 0xf095, 0xf3dd, 0xf04d, 0xf2f2, 0xf024, 0xf252, 0xf569, 0xf201, 0xf06e, 0xf015, 0xf072`
* Click on Convert, and download the file `jetbrains_mono_bold_20.c` and copy it in `src/DisplayApp/Fonts`
* Add the font .c file path to src/CMakeLists.txt
* Add an LV_FONT_DECLARE line in src/libs/lv_conf.h

View File

@ -840,6 +840,16 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
0xf8, 0xf, 0x80, 0xf8, 0x3e, 0x0, 0xff, 0xf0,
0x0, 0x3f, 0x80, 0x0,
/* U+F072 "" */
0x1, 0xc0, 0x0, 0x7, 0xc0, 0x0, 0x7, 0x80,
0x0, 0xf, 0x80, 0x0, 0x1f, 0x0, 0x0, 0x1f,
0x0, 0x38, 0x3e, 0x0, 0x78, 0x7e, 0x0, 0x7f,
0xff, 0xe0, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xf3,
0xff, 0xff, 0xe7, 0xff, 0xff, 0xdf, 0xff, 0xfc,
0x3c, 0x3f, 0x0, 0x70, 0x7c, 0x0, 0x1, 0xf0,
0x0, 0x3, 0xe0, 0x0, 0x7, 0x80, 0x0, 0xf,
0x0, 0x0, 0x1c, 0x0, 0x0,
/* U+F095 "" */
0x0, 0x0, 0x0, 0x0, 0x3e, 0x0, 0x7, 0xf0,
0x0, 0x7f, 0x0, 0x7, 0xf0, 0x0, 0xff, 0x0,
@ -1220,31 +1230,32 @@ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
{.bitmap_index = 3028, .adv_w = 280, .box_w = 13, .box_h = 17, .ofs_x = 2, .ofs_y = -1},
{.bitmap_index = 3056, .adv_w = 320, .box_w = 19, .box_h = 20, .ofs_x = 0, .ofs_y = -3},
{.bitmap_index = 3104, .adv_w = 360, .box_w = 23, .box_h = 15, .ofs_x = 0, .ofs_y = 0},
{.bitmap_index = 3148, .adv_w = 320, .box_w = 20, .box_h = 21, .ofs_x = 0, .ofs_y = -3},
{.bitmap_index = 3201, .adv_w = 120, .box_w = 8, .box_h = 19, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3220, .adv_w = 320, .box_w = 20, .box_h = 20, .ofs_x = 0, .ofs_y = -3},
{.bitmap_index = 3270, .adv_w = 240, .box_w = 15, .box_h = 19, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3306, .adv_w = 320, .box_w = 20, .box_h = 19, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3354, .adv_w = 320, .box_w = 21, .box_h = 15, .ofs_x = 0, .ofs_y = 0},
{.bitmap_index = 3394, .adv_w = 320, .box_w = 20, .box_h = 17, .ofs_x = 0, .ofs_y = -1},
{.bitmap_index = 3437, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1},
{.bitmap_index = 3475, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1},
{.bitmap_index = 3513, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1},
{.bitmap_index = 3551, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1},
{.bitmap_index = 3589, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1},
{.bitmap_index = 3627, .adv_w = 240, .box_w = 15, .box_h = 19, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3663, .adv_w = 280, .box_w = 15, .box_h = 20, .ofs_x = 1, .ofs_y = -3},
{.bitmap_index = 3701, .adv_w = 200, .box_w = 11, .box_h = 21, .ofs_x = 0, .ofs_y = -3},
{.bitmap_index = 3730, .adv_w = 280, .box_w = 16, .box_h = 19, .ofs_x = 1, .ofs_y = -2},
{.bitmap_index = 3768, .adv_w = 400, .box_w = 25, .box_h = 21, .ofs_x = 0, .ofs_y = -3},
{.bitmap_index = 3834, .adv_w = 360, .box_w = 23, .box_h = 17, .ofs_x = 0, .ofs_y = -1},
{.bitmap_index = 3883, .adv_w = 320, .box_w = 20, .box_h = 20, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3933, .adv_w = 400, .box_w = 25, .box_h = 19, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3993, .adv_w = 320, .box_w = 20, .box_h = 21, .ofs_x = 0, .ofs_y = -3},
{.bitmap_index = 4046, .adv_w = 360, .box_w = 23, .box_h = 21, .ofs_x = 0, .ofs_y = -3},
{.bitmap_index = 4107, .adv_w = 360, .box_w = 22, .box_h = 20, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 4162, .adv_w = 360, .box_w = 22, .box_h = 19, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 4215, .adv_w = 320, .box_w = 20, .box_h = 15, .ofs_x = 0, .ofs_y = 0}
{.bitmap_index = 3148, .adv_w = 360, .box_w = 23, .box_h = 21, .ofs_x = 0, .ofs_y = -3},
{.bitmap_index = 3209, .adv_w = 320, .box_w = 20, .box_h = 21, .ofs_x = 0, .ofs_y = -3},
{.bitmap_index = 3262, .adv_w = 120, .box_w = 8, .box_h = 19, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3281, .adv_w = 320, .box_w = 20, .box_h = 20, .ofs_x = 0, .ofs_y = -3},
{.bitmap_index = 3331, .adv_w = 240, .box_w = 15, .box_h = 19, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3367, .adv_w = 320, .box_w = 20, .box_h = 19, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3415, .adv_w = 320, .box_w = 21, .box_h = 15, .ofs_x = 0, .ofs_y = 0},
{.bitmap_index = 3455, .adv_w = 320, .box_w = 20, .box_h = 17, .ofs_x = 0, .ofs_y = -1},
{.bitmap_index = 3498, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1},
{.bitmap_index = 3536, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1},
{.bitmap_index = 3574, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1},
{.bitmap_index = 3612, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1},
{.bitmap_index = 3650, .adv_w = 400, .box_w = 25, .box_h = 12, .ofs_x = 0, .ofs_y = 1},
{.bitmap_index = 3688, .adv_w = 240, .box_w = 15, .box_h = 19, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3724, .adv_w = 280, .box_w = 15, .box_h = 20, .ofs_x = 1, .ofs_y = -3},
{.bitmap_index = 3762, .adv_w = 200, .box_w = 11, .box_h = 21, .ofs_x = 0, .ofs_y = -3},
{.bitmap_index = 3791, .adv_w = 280, .box_w = 16, .box_h = 19, .ofs_x = 1, .ofs_y = -2},
{.bitmap_index = 3829, .adv_w = 400, .box_w = 25, .box_h = 21, .ofs_x = 0, .ofs_y = -3},
{.bitmap_index = 3895, .adv_w = 360, .box_w = 23, .box_h = 17, .ofs_x = 0, .ofs_y = -1},
{.bitmap_index = 3944, .adv_w = 320, .box_w = 20, .box_h = 20, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 3994, .adv_w = 400, .box_w = 25, .box_h = 19, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 4054, .adv_w = 320, .box_w = 20, .box_h = 21, .ofs_x = 0, .ofs_y = -3},
{.bitmap_index = 4107, .adv_w = 360, .box_w = 23, .box_h = 21, .ofs_x = 0, .ofs_y = -3},
{.bitmap_index = 4168, .adv_w = 360, .box_w = 22, .box_h = 20, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 4223, .adv_w = 360, .box_w = 22, .box_h = 19, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 4276, .adv_w = 320, .box_w = 20, .box_h = 15, .ofs_x = 0, .ofs_y = 0}
};
/*---------------------
@ -1253,10 +1264,11 @@ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
static const uint16_t unicode_list_2[] = {
0x0, 0x14, 0x16, 0x23, 0x26, 0x27, 0x28, 0x39,
0x47, 0x4a, 0x4b, 0x4c, 0x50, 0x68, 0x6d, 0x94,
0x128, 0x184, 0x1e5, 0x1fb, 0x200, 0x21d, 0x23f, 0x240,
0x241, 0x242, 0x243, 0x251, 0x292, 0x293, 0x2f1, 0x3dc,
0x3fc, 0x45c, 0x54a, 0x55f, 0x568, 0x59e, 0x59f, 0x6a8
0x47, 0x4a, 0x4b, 0x4c, 0x50, 0x68, 0x6d, 0x71,
0x94, 0x128, 0x184, 0x1e5, 0x1fb, 0x200, 0x21d, 0x23f,
0x240, 0x241, 0x242, 0x243, 0x251, 0x292, 0x293, 0x2f1,
0x3dc, 0x3fc, 0x45c, 0x54a, 0x55f, 0x568, 0x59e, 0x59f,
0x6a8
};
/*Collect the unicode lists and glyph_id offsets*/
@ -1272,7 +1284,7 @@ static const lv_font_fmt_txt_cmap_t cmaps[] =
},
{
.range_start = 61441, .range_length = 1705, .glyph_id_start = 160,
.unicode_list = unicode_list_2, .glyph_id_ofs_list = NULL, .list_length = 40, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY
.unicode_list = unicode_list_2, .glyph_id_ofs_list = NULL, .list_length = 41, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY
}
};
@ -1321,7 +1333,7 @@ lv_font_t jetbrains_mono_bold_20 = {
#if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0)
.subpx = LV_FONT_SUBPX_NONE,
#endif
#if LV_VERSION_CHECK(7, 4, 0)
#if LV_VERSION_CHECK(7, 4, 0) || LVGL_VERSION_MAJOR >= 8
.underline_position = -3,
.underline_thickness = 1,
#endif

View File

@ -2,9 +2,14 @@
#include "displayapp/screens/Symbols.h"
using namespace Pinetime::Applications::Screens;
const char* BleIcon::GetIcon(bool isConnected) {
if (isConnected)
const char* BleIcon::GetIcon(bool isRadioEnabled, bool isConnected) {
if(!isRadioEnabled) {
return Symbols::airplane;
}
if (isConnected) {
return Symbols::bluetooth;
else
return "";
}
}
return Symbols::none;
}

View File

@ -1,12 +1,14 @@
#pragma once
#include "components/ble/BleController.h"
namespace Pinetime {
namespace Applications {
namespace Screens {
class BleIcon {
public:
static const char* GetIcon(bool isConnected);
static const char* GetIcon(bool isRadioEnabled, bool isConnected);
};
}
}
}
}

View File

@ -42,6 +42,13 @@ namespace {
auto* screen = static_cast<PineTimeStyle*>(obj->user_data);
screen->UpdateSelected(obj, event);
}
bool IsBleIconVisible(bool isRadioEnabled, bool isConnected) {
if(!isRadioEnabled) {
return true;
}
return isConnected;
}
}
PineTimeStyle::PineTimeStyle(DisplayApp* app,
@ -336,11 +343,13 @@ void PineTimeStyle::SetBatteryIcon() {
lv_label_set_text_static(batteryIcon, BatteryIcon::GetBatteryIcon(batteryPercent));
}
void PineTimeStyle::AlignIcons() {
if (notificationState.Get() && bleState.Get()) {
bool isBleIconVisible = IsBleIconVisible(bleRadioEnabled.Get(), bleState.Get());
if (notificationState.Get() && isBleIconVisible) {
lv_obj_align(bleIcon, sidebar, LV_ALIGN_IN_TOP_MID, 8, 25);
lv_obj_align(notificationIcon, sidebar, LV_ALIGN_IN_TOP_MID, -8, 25);
} else if (notificationState.Get() && !bleState.Get()) {
} else if (notificationState.Get() && !isBleIconVisible) {
lv_obj_align(notificationIcon, sidebar, LV_ALIGN_IN_TOP_MID, 0, 25);
} else {
lv_obj_align(bleIcon, sidebar, LV_ALIGN_IN_TOP_MID, 0, 25);
@ -364,8 +373,9 @@ void PineTimeStyle::Refresh() {
}
bleState = bleController.IsConnected();
if (bleState.IsUpdated()) {
lv_label_set_text_static(bleIcon, BleIcon::GetIcon(bleState.Get()));
bleRadioEnabled = bleController.IsRadioEnabled();
if (bleState.IsUpdated() || bleRadioEnabled.IsUpdated()) {
lv_label_set_text(bleIcon, BleIcon::GetIcon(bleRadioEnabled.Get(), bleState.Get()));
AlignIcons();
}

View File

@ -7,6 +7,7 @@
#include "displayapp/screens/Screen.h"
#include "displayapp/Colors.h"
#include "components/datetime/DateTimeController.h"
#include "components/ble/BleController.h"
namespace Pinetime {
namespace Controllers {
@ -43,14 +44,15 @@ namespace Pinetime {
uint8_t displayedMinute = -1;
uint16_t currentYear = 1970;
Pinetime::Controllers::DateTime::Months currentMonth = Pinetime::Controllers::DateTime::Months::Unknown;
Pinetime::Controllers::DateTime::Days currentDayOfWeek = Pinetime::Controllers::DateTime::Days::Unknown;
Controllers::DateTime::Months currentMonth = Pinetime::Controllers::DateTime::Months::Unknown;
Controllers::DateTime::Days currentDayOfWeek = Pinetime::Controllers::DateTime::Days::Unknown;
uint8_t currentDay = 0;
uint32_t savedTick = 0;
DirtyValue<uint8_t> batteryPercentRemaining {};
DirtyValue<bool> isCharging {};
DirtyValue<bool> bleState {};
DirtyValue<bool> bleRadioEnabled {};
DirtyValue<std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds>> currentDateTime {};
DirtyValue<bool> motionSensorOk {};
DirtyValue<uint32_t> stepCount {};

View File

@ -44,6 +44,7 @@ namespace Pinetime {
static constexpr const char* chartLine = "\xEF\x88\x81";
static constexpr const char* eye = "\xEF\x81\xAE";
static constexpr const char* home = "\xEF\x80\x95";
static constexpr const char* airplane = "\xEF\x81\xB2";
// lv_font_sys_48.c
static constexpr const char* settings = "\xEE\xA4\x82"; // e902

View File

@ -120,8 +120,9 @@ void WatchFaceDigital::Refresh() {
}
bleState = bleController.IsConnected();
if (bleState.IsUpdated()) {
lv_label_set_text_static(bleIcon, BleIcon::GetIcon(bleState.Get()));
bleRadioEnabled = bleController.IsRadioEnabled();
if (bleState.IsUpdated() || bleRadioEnabled.IsUpdated()) {
lv_label_set_text(bleIcon, BleIcon::GetIcon(bleRadioEnabled.Get(), bleState.Get()));
}
lv_obj_realign(batteryIcon);
lv_obj_realign(batteryPlug);

View File

@ -6,6 +6,7 @@
#include <memory>
#include "displayapp/screens/Screen.h"
#include "components/datetime/DateTimeController.h"
#include "components/ble/BleController.h"
namespace Pinetime {
namespace Controllers {
@ -39,13 +40,14 @@ namespace Pinetime {
uint8_t displayedMinute = -1;
uint16_t currentYear = 1970;
Pinetime::Controllers::DateTime::Months currentMonth = Pinetime::Controllers::DateTime::Months::Unknown;
Pinetime::Controllers::DateTime::Days currentDayOfWeek = Pinetime::Controllers::DateTime::Days::Unknown;
Controllers::DateTime::Months currentMonth = Pinetime::Controllers::DateTime::Months::Unknown;
Controllers::DateTime::Days currentDayOfWeek = Pinetime::Controllers::DateTime::Days::Unknown;
uint8_t currentDay = 0;
DirtyValue<uint8_t> batteryPercentRemaining {};
DirtyValue<bool> powerPresent {};
DirtyValue<bool> bleState {};
DirtyValue<bool> bleRadioEnabled {};
DirtyValue<std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds>> currentDateTime {};
DirtyValue<bool> motionSensorOk {};
DirtyValue<uint32_t> stepCount {};

View File

@ -114,11 +114,16 @@ void WatchFaceTerminal::Refresh() {
}
bleState = bleController.IsConnected();
if (bleState.IsUpdated()) {
if (bleState.Get()) {
lv_label_set_text_static(connectState, "[STAT]#387b54 Connected#");
bleRadioEnabled = bleController.IsRadioEnabled();
if (bleState.IsUpdated() || bleRadioEnabled.IsUpdated()) {
if(!bleRadioEnabled.Get()) {
lv_label_set_text_static(connectState, "[STAT]#387b54 Disabled#");
} else {
lv_label_set_text_static(connectState, "[STAT]#387b54 Disconnected#");
if (bleState.Get()) {
lv_label_set_text_static(connectState, "[STAT]#387b54 Connected#");
} else {
lv_label_set_text_static(connectState, "[STAT]#387b54 Disconnected#");
}
}
}

View File

@ -47,6 +47,7 @@ namespace Pinetime {
DirtyValue<int> batteryPercentRemaining {};
DirtyValue<bool> powerPresent {};
DirtyValue<bool> bleState {};
DirtyValue<bool> bleRadioEnabled {};
DirtyValue<std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds>> currentDateTime {};
DirtyValue<bool> motionSensorOk {};
DirtyValue<uint32_t> stepCount {};

View File

@ -0,0 +1,93 @@
#include "displayapp/screens/settings/SettingAirplaneMode.h"
#include <lvgl/lvgl.h>
#include "displayapp/DisplayApp.h"
#include "displayapp/Messages.h"
#include "displayapp/screens/Styles.h"
#include "displayapp/screens/Screen.h"
#include "displayapp/screens/Symbols.h"
using namespace Pinetime::Applications::Screens;
namespace {
static void OnAirplaneModeEnabledEvent(lv_obj_t* obj, lv_event_t event) {
auto* screen = static_cast<SettingAirplaneMode*>(obj->user_data);
screen->OnAirplaneModeEnabled(obj, event);
}
static void OnAirplaneModeDisabledEvent(lv_obj_t* obj, lv_event_t event) {
auto* screen = static_cast<SettingAirplaneMode*>(obj->user_data);
screen->OnAirplaneModeDisabled(obj, event);
}
}
SettingAirplaneMode::SettingAirplaneMode(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Settings& settingsController)
: Screen(app), settingsController {settingsController} {
lv_obj_t* container1 = lv_cont_create(lv_scr_act(), nullptr);
lv_obj_set_style_local_bg_opa(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP);
lv_obj_set_style_local_pad_all(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 10);
lv_obj_set_style_local_pad_inner(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 5);
lv_obj_set_style_local_border_width(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0);
lv_obj_set_pos(container1, 10, 60);
lv_obj_set_width(container1, LV_HOR_RES - 20);
lv_obj_set_height(container1, LV_VER_RES - 50);
lv_cont_set_layout(container1, LV_LAYOUT_COLUMN_LEFT);
lv_obj_t* title = lv_label_create(lv_scr_act(), nullptr);
lv_label_set_text_static(title, "Airplane mode");
lv_label_set_align(title, LV_LABEL_ALIGN_CENTER);
lv_obj_align(title, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 15, 15);
lv_obj_t* icon = lv_label_create(lv_scr_act(), nullptr);
lv_obj_set_style_local_text_color(icon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_ORANGE);
lv_label_set_text_static(icon, Symbols::airplane);
lv_label_set_align(icon, LV_LABEL_ALIGN_CENTER);
lv_obj_align(icon, title, LV_ALIGN_OUT_LEFT_MID, -10, 0);
cbEnabled = lv_checkbox_create(container1, nullptr);
lv_checkbox_set_text(cbEnabled, " Enable");
cbEnabled->user_data = this;
lv_obj_set_event_cb(cbEnabled, OnAirplaneModeEnabledEvent);
SetRadioButtonStyle(cbEnabled);
cbDisabled = lv_checkbox_create(container1, nullptr);
lv_checkbox_set_text(cbDisabled, " Disable");
cbDisabled->user_data = this;
lv_obj_set_event_cb(cbDisabled, OnAirplaneModeDisabledEvent);
SetRadioButtonStyle(cbDisabled);
if (settingsController.GetBleRadioEnabled()) {
lv_checkbox_set_checked(cbDisabled, true);
priorMode = true;
} else {
lv_checkbox_set_checked(cbEnabled, true);
priorMode = false;
}
}
SettingAirplaneMode::~SettingAirplaneMode() {
lv_obj_clean(lv_scr_act());
// Do not call SaveSettings - see src/components/settings/Settings.h
if (priorMode != settingsController.GetBleRadioEnabled()) {
app->PushMessage(Pinetime::Applications::Display::Messages::BleRadioEnableToggle);
}
}
void SettingAirplaneMode::OnAirplaneModeEnabled(lv_obj_t* object, lv_event_t event) {
if (event == LV_EVENT_VALUE_CHANGED) {
lv_checkbox_set_checked(cbEnabled, true);
lv_checkbox_set_checked(cbDisabled, false);
settingsController.SetBleRadioEnabled(false);
}
}
void SettingAirplaneMode::OnAirplaneModeDisabled(lv_obj_t* object, lv_event_t event) {
if (event == LV_EVENT_VALUE_CHANGED) {
lv_checkbox_set_checked(cbEnabled, false);
lv_checkbox_set_checked(cbDisabled, true);
settingsController.SetBleRadioEnabled(true);
}
}

View File

@ -0,0 +1,31 @@
#pragma once
#include <array>
#include <cstdint>
#include <lvgl/lvgl.h>
#include "components/settings/Settings.h"
#include "displayapp/screens/Screen.h"
namespace Pinetime {
namespace Applications {
namespace Screens {
class SettingAirplaneMode : public Screen {
public:
SettingAirplaneMode(DisplayApp* app, Pinetime::Controllers::Settings& settingsController);
~SettingAirplaneMode() override;
void OnAirplaneModeEnabled(lv_obj_t* object, lv_event_t event);
void OnAirplaneModeDisabled(lv_obj_t* object, lv_event_t event);
private:
Controllers::Settings& settingsController;
lv_obj_t* cbEnabled;
lv_obj_t* cbDisabled;
bool priorMode;
};
}
}
}

View File

@ -21,7 +21,11 @@ Settings::Settings(Pinetime::Applications::DisplayApp* app, Pinetime::Controller
},
[this]() -> std::unique_ptr<Screen> {
return CreateScreen3();
}},
},
[this]() -> std::unique_ptr<Screen> {
return CreateScreen4();
},
},
Screens::ScreenListModes::UpDown} {
}
@ -34,7 +38,6 @@ bool Settings::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
}
std::unique_ptr<Screen> Settings::CreateScreen1() {
std::array<Screens::List::Applications, 4> applications {{
{Symbols::sun, "Display", Apps::SettingDisplay},
{Symbols::eye, "Wake Up", Apps::SettingWakeUp},
@ -42,17 +45,17 @@ std::unique_ptr<Screen> Settings::CreateScreen1() {
{Symbols::home, "Watch face", Apps::SettingWatchFace},
}};
return std::make_unique<Screens::List>(0, 3, app, settingsController, applications);
return std::make_unique<Screens::List>(0, 4, app, settingsController, applications);
}
std::unique_ptr<Screen> Settings::CreateScreen2() {
std::array<Screens::List::Applications, 4> applications {{
{Symbols::shoe, "Steps", Apps::SettingSteps},
{Symbols::clock, "Set date", Apps::SettingSetDate},
{Symbols::clock, "Set time", Apps::SettingSetTime},
{Symbols::batteryHalf, "Battery", Apps::BatteryInfo}}};
std::array<Screens::List::Applications, 4> applications {{{Symbols::shoe, "Steps", Apps::SettingSteps},
{Symbols::clock, "Set date", Apps::SettingSetDate},
{Symbols::clock, "Set time", Apps::SettingSetTime},
{Symbols::batteryHalf, "Battery", Apps::BatteryInfo}}};
return std::make_unique<Screens::List>(1, 3, app, settingsController, applications);
return std::make_unique<Screens::List>(1, 4, app, settingsController, applications);
}
std::unique_ptr<Screen> Settings::CreateScreen3() {
@ -61,8 +64,20 @@ std::unique_ptr<Screen> Settings::CreateScreen3() {
{Symbols::clock, "Chimes", Apps::SettingChimes},
{Symbols::tachometer, "Shake Calib.", Apps::SettingShakeThreshold},
{Symbols::check, "Firmware", Apps::FirmwareValidation},
{Symbols::list, "About", Apps::SysInfo}
{Symbols::list, "Airplane mode", Apps::SettingAirplaneMode}
}};
return std::make_unique<Screens::List>(2, 3, app, settingsController, applications);
return std::make_unique<Screens::List>(2, 4, app, settingsController, applications);
}
std::unique_ptr<Screen> Settings::CreateScreen4() {
std::array<Screens::List::Applications, 4> applications {{
{Symbols::list, "About", Apps::SysInfo},
{Symbols::none, "None", Apps::None},
{Symbols::none, "None", Apps::None},
{Symbols::none, "None", Apps::None}
}};
return std::make_unique<Screens::List>(3, 4, app, settingsController, applications);
}

View File

@ -19,11 +19,12 @@ namespace Pinetime {
private:
Controllers::Settings& settingsController;
ScreenList<3> screens;
ScreenList<4> screens;
std::unique_ptr<Screen> CreateScreen1();
std::unique_ptr<Screen> CreateScreen2();
std::unique_ptr<Screen> CreateScreen3();
std::unique_ptr<Screen> CreateScreen4();
};
}
}

View File

@ -31,6 +31,7 @@ namespace Pinetime {
BatteryPercentageUpdated,
StartFileTransfer,
StopFileTransfer,
BleRadioEnableToggle
};
}
}

View File

@ -254,7 +254,7 @@ void SystemTask::Work() {
displayApp.PushMessage(Pinetime::Applications::Display::Messages::GoToRunning);
heartRateApp.PushMessage(Pinetime::Applications::HeartRateTask::Messages::WakeUp);
if (!bleController.IsConnected()) {
if (bleController.IsRadioEnabled() && !bleController.IsConnected()) {
nimbleController.RestartFastAdv();
}
@ -440,7 +440,13 @@ void SystemTask::Work() {
motorController.RunForDuration(35);
displayApp.PushMessage(Pinetime::Applications::Display::Messages::ShowPairingKey);
break;
case Messages::BleRadioEnableToggle:
if(settingsController.GetBleRadioEnabled()) {
nimbleController.EnableRadio();
} else {
nimbleController.DisableRadio();
}
break;
default:
break;
}