Feature additions (#434)

Lots of things "ported" over from the "enhanced" fork. With some adjustments here and there.

KeyboardBacklight driver (for T-Deck only currently)
Trackball driver (for T-Deck only currently)
Keyboard backlight sleep/wake (for T-Deck only currently...also requires keyboard firmware update)
Display sleep/wake
Files - create file/folder
Keyboard settings (for T-Deck only currently)
Time & Date settings tweaks
Locale settings tweaks
Systeminfo additions
Espnow wifi coexist

initI2cDevices - moved to T-deck init.cpp / initBoot
KeyboardInitService - removed,  moved to T-deck init.cpp / initBoot
Adjusted TIMER_UPDATE_INTERVAL to 2 seconds.
Added lock to ActionCreateFolder

Maybe missed some things in the list.

Display wake could do with some kind of block on wake first touch to prevent UI elements being hit when waking device with touch. Same with encoder/trackball/keyboard press i guess.

The original code was written by @cscott0108 at https://github.com/cscott0108/tactility-enhanced-t-deck
This commit is contained in:
Shadowtrance
2026-01-02 21:14:55 +10:00
committed by GitHub
parent feaeb11e49
commit a4dc633063
34 changed files with 1916 additions and 113 deletions
@@ -8,6 +8,7 @@
#include <Tactility/settings/Time.h>
#include <Tactility/StringUtils.h>
#include <Tactility/settings/Language.h>
#include <Tactility/settings/SystemSettings.h>
#include <lvgl.h>
#include <map>
@@ -28,14 +29,9 @@ extern const AppManifest manifest;
class LocaleSettingsApp final : public App {
tt::i18n::TextResources textResources = tt::i18n::TextResources(TEXT_RESOURCE_PATH);
RecursiveMutex mutex;
lv_obj_t* timeZoneLabel = nullptr;
lv_obj_t* regionLabel = nullptr;
lv_obj_t* regionTextArea = nullptr;
lv_obj_t* languageDropdown = nullptr;
lv_obj_t* languageLabel = nullptr;
static void onConfigureTimeZonePressed(TT_UNUSED lv_event_t* event) {
timezone::start();
}
bool settingsUpdated = false;
std::map<settings::Language, std::string> languageMap;
@@ -68,9 +64,6 @@ class LocaleSettingsApp final : public App {
void updateViews() {
textResources.load();
lv_label_set_text(regionLabel , textResources[i18n::Text::REGION].c_str());
lv_label_set_text(languageLabel, textResources[i18n::Text::LANGUAGE].c_str());
std::string language_options = getLanguageOptions();
lv_dropdown_set_options(languageDropdown, language_options.c_str());
lv_dropdown_set_selected(languageDropdown, static_cast<uint32_t>(settings::getLanguage()));
@@ -86,6 +79,11 @@ class LocaleSettingsApp final : public App {
self->updateViews();
}
static void onRegionChanged(lv_event_t* event) {
auto* self = static_cast<LocaleSettingsApp*>(lv_event_get_user_data(event));
self->settingsUpdated = true;
}
public:
void onShow(AppContext& app, lv_obj_t* parent) override {
@@ -108,42 +106,42 @@ public:
auto* region_wrapper = lv_obj_create(main_wrapper);
lv_obj_set_width(region_wrapper, LV_PCT(100));
lv_obj_set_height(region_wrapper, LV_SIZE_CONTENT);
lv_obj_set_style_pad_all(region_wrapper, 0, 0);
lv_obj_set_style_pad_all(region_wrapper, 8, 0);
lv_obj_set_style_border_width(region_wrapper, 0, 0);
regionLabel = lv_label_create(region_wrapper);
lv_label_set_text(regionLabel , textResources[i18n::Text::REGION].c_str());
lv_obj_align(regionLabel , LV_ALIGN_LEFT_MID, 0, 0);
auto* region_label = lv_label_create(region_wrapper);
lv_label_set_text(region_label, textResources[i18n::Text::REGION].c_str());
lv_obj_align(region_label, LV_ALIGN_LEFT_MID, 4, 0);
auto* region_button = lv_button_create(region_wrapper);
lv_obj_align(region_button, LV_ALIGN_RIGHT_MID, 0, 0);
auto* region_button_image = lv_image_create(region_button);
lv_obj_add_event_cb(region_button, onConfigureTimeZonePressed, LV_EVENT_SHORT_CLICKED, nullptr);
lv_image_set_src(region_button_image, LV_SYMBOL_SETTINGS);
timeZoneLabel = lv_label_create(region_wrapper);
std::string timeZoneName = settings::getTimeZoneName();
if (timeZoneName.empty()) {
timeZoneName = "not set";
// Region text area for user input (e.g., US, EU, JP)
regionTextArea = lv_textarea_create(region_wrapper);
lv_obj_set_width(regionTextArea, 120);
lv_textarea_set_one_line(regionTextArea, true);
lv_textarea_set_max_length(regionTextArea, 50);
lv_textarea_set_placeholder_text(regionTextArea, "e.g. US, EU");
// Load current region from settings
settings::SystemSettings sysSettings;
if (settings::loadSystemSettings(sysSettings)) {
lv_textarea_set_text(regionTextArea, sysSettings.region.c_str());
}
lv_label_set_text(timeZoneLabel, timeZoneName.c_str());
const int offset = ui_scale == hal::UiScale::Smallest ? -2 : -10;
lv_obj_align_to(timeZoneLabel, region_button, LV_ALIGN_OUT_LEFT_MID, offset, 0);
lv_obj_add_event_cb(regionTextArea, onRegionChanged, LV_EVENT_VALUE_CHANGED, this);
lv_obj_align(regionTextArea, LV_ALIGN_RIGHT_MID, 0, 0);
// Language
auto* language_wrapper = lv_obj_create(main_wrapper);
lv_obj_set_width(language_wrapper, LV_PCT(100));
lv_obj_set_height(language_wrapper, LV_SIZE_CONTENT);
lv_obj_set_style_pad_all(language_wrapper, 0, 0);
lv_obj_set_style_pad_all(language_wrapper, 8, 0);
lv_obj_set_style_border_width(language_wrapper, 0, 0);
languageLabel = lv_label_create(language_wrapper);
auto* languageLabel = lv_label_create(language_wrapper);
lv_label_set_text(languageLabel, textResources[i18n::Text::LANGUAGE].c_str());
lv_obj_align(languageLabel, LV_ALIGN_LEFT_MID, 0, 0);
lv_obj_align(languageLabel, LV_ALIGN_LEFT_MID, 4, 0);
languageDropdown = lv_dropdown_create(language_wrapper);
lv_obj_set_width(languageDropdown, 150);
lv_obj_align(languageDropdown, LV_ALIGN_RIGHT_MID, 0, 0);
std::string language_options = getLanguageOptions();
lv_dropdown_set_options(languageDropdown, language_options.c_str());
@@ -151,18 +149,12 @@ public:
lv_obj_add_event_cb(languageDropdown, onLanguageSet, LV_EVENT_VALUE_CHANGED, this);
}
void onResult(AppContext& app, TT_UNUSED LaunchId launchId, Result result, std::unique_ptr<Bundle> bundle) override {
if (result == Result::Ok && bundle != nullptr) {
const auto name = timezone::getResultName(*bundle);
const auto code = timezone::getResultCode(*bundle);
TT_LOG_I(TAG, "Result name=%s code=%s", name.c_str(), code.c_str());
settings::setTimeZone(name, code);
if (!name.empty()) {
if (lvgl::lock(100 / portTICK_PERIOD_MS)) {
lv_label_set_text(timeZoneLabel, name.c_str());
lvgl::unlock();
}
void onHide(TT_UNUSED AppContext& app) override {
if (settingsUpdated && regionTextArea) {
settings::SystemSettings sysSettings;
if (settings::loadSystemSettings(sysSettings)) {
sysSettings.region = lv_textarea_get_text(regionTextArea);
settings::saveSystemSettings(sysSettings);
}
}
}