Various improvements (#204)

- Fixed crash in logging app when not selecting filter
- Cleanup of unused code
- Cleanup of app code
This commit is contained in:
Ken Van Hoeylandt 2025-02-04 23:05:28 +01:00 committed by GitHub
parent 5ec96f60f1
commit 68e34ca740
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 82 additions and 126 deletions

View File

@ -1,7 +0,0 @@
#pragma once
#include <Tactility/hal/Display.h>
namespace tt::lvgl {
hal::Display* getDisplay();
}

View File

@ -6,15 +6,8 @@ namespace tt::lvgl {
void obj_set_style_bg_blacken(lv_obj_t* obj); void obj_set_style_bg_blacken(lv_obj_t* obj);
void obj_set_style_bg_invisible(lv_obj_t* obj); void obj_set_style_bg_invisible(lv_obj_t* obj);
[[deprecated("use _pad_all() and _pad_gap() individually")]]
void obj_set_style_no_padding(lv_obj_t* obj); void obj_set_style_no_padding(lv_obj_t* obj);
/**
* This is to create automatic padding depending on the screen size.
* The larger the screen, the more padding it gets.
* TODO: It currently only applies a single basic padding, but will be improved later.
*
* @param obj
*/
void obj_set_style_auto_padding(lv_obj_t* obj);
} // namespace } // namespace

View File

@ -2,7 +2,6 @@
#include "Tactility/app/AppContext.h" #include "Tactility/app/AppContext.h"
#include "Tactility/app/display/DisplaySettings.h" #include "Tactility/app/display/DisplaySettings.h"
#include "Tactility/app/launcher/Launcher.h"
#include "Tactility/service/loader/Loader.h" #include "Tactility/service/loader/Loader.h"
#include "Tactility/lvgl/Style.h" #include "Tactility/lvgl/Style.h"

View File

@ -106,30 +106,30 @@ class DisplayApp : public App {
lvgl::toolbar_create(parent, app); lvgl::toolbar_create(parent, app);
lv_obj_t* main_wrapper = lv_obj_create(parent); auto* main_wrapper = lv_obj_create(parent);
lv_obj_set_flex_flow(main_wrapper, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_flow(main_wrapper, LV_FLEX_FLOW_COLUMN);
lv_obj_set_width(main_wrapper, LV_PCT(100)); lv_obj_set_width(main_wrapper, LV_PCT(100));
lv_obj_set_flex_grow(main_wrapper, 1); lv_obj_set_flex_grow(main_wrapper, 1);
lv_obj_t* wrapper = lv_obj_create(main_wrapper); auto* wrapper = lv_obj_create(main_wrapper);
lv_obj_set_width(wrapper, LV_PCT(100)); lv_obj_set_width(wrapper, LV_PCT(100));
lv_obj_set_style_pad_all(wrapper, 8, 0); lv_obj_set_style_pad_all(wrapper, 8, 0);
lv_obj_set_style_border_width(wrapper, 0, 0); lv_obj_set_style_border_width(wrapper, 0, 0);
lv_obj_t* brightness_label = lv_label_create(wrapper); auto* brightness_label = lv_label_create(wrapper);
lv_label_set_text(brightness_label, "Brightness"); lv_label_set_text(brightness_label, "Brightness");
lv_obj_t* brightness_slider = lv_slider_create(wrapper); auto* brightness_slider = lv_slider_create(wrapper);
lv_obj_set_width(brightness_slider, LV_PCT(50)); lv_obj_set_width(brightness_slider, LV_PCT(50));
lv_obj_align(brightness_slider, LV_ALIGN_TOP_RIGHT, -8, 0); lv_obj_align(brightness_slider, LV_ALIGN_TOP_RIGHT, -8, 0);
lv_slider_set_range(brightness_slider, 0, 255); lv_slider_set_range(brightness_slider, 0, 255);
lv_obj_add_event_cb(brightness_slider, onBacklightSliderEvent, LV_EVENT_VALUE_CHANGED, nullptr); lv_obj_add_event_cb(brightness_slider, onBacklightSliderEvent, LV_EVENT_VALUE_CHANGED, nullptr);
lv_obj_t* gamma_label = lv_label_create(wrapper); auto* gamma_label = lv_label_create(wrapper);
lv_label_set_text(gamma_label, "Gamma"); lv_label_set_text(gamma_label, "Gamma");
lv_obj_set_y(gamma_label, 40); lv_obj_set_y(gamma_label, 40);
lv_obj_t* gamma_slider = lv_slider_create(wrapper); auto* gamma_slider = lv_slider_create(wrapper);
lv_obj_set_width(gamma_slider, LV_PCT(50)); lv_obj_set_width(gamma_slider, LV_PCT(50));
lv_obj_align(gamma_slider, LV_ALIGN_TOP_RIGHT, -8, 40); lv_obj_align(gamma_slider, LV_ALIGN_TOP_RIGHT, -8, 40);
lv_slider_set_range(gamma_slider, 0, hal_display->getGammaCurveCount()); lv_slider_set_range(gamma_slider, 0, hal_display->getGammaCurveCount());
@ -145,7 +145,7 @@ class DisplayApp : public App {
lv_slider_set_value(gamma_slider, 128, LV_ANIM_OFF); lv_slider_set_value(gamma_slider, 128, LV_ANIM_OFF);
lv_obj_t* orientation_label = lv_label_create(wrapper); auto* orientation_label = lv_label_create(wrapper);
lv_label_set_text(orientation_label, "Orientation"); lv_label_set_text(orientation_label, "Orientation");
lv_obj_align(orientation_label, LV_ALIGN_TOP_LEFT, 0, 80); lv_obj_align(orientation_label, LV_ALIGN_TOP_LEFT, 0, 80);
@ -154,7 +154,7 @@ class DisplayApp : public App {
auto vertical_px = lv_display_get_vertical_resolution(lvgl_display); auto vertical_px = lv_display_get_vertical_resolution(lvgl_display);
bool is_landscape_display = horizontal_px > vertical_px; bool is_landscape_display = horizontal_px > vertical_px;
lv_obj_t* orientation_dropdown = lv_dropdown_create(wrapper); auto* orientation_dropdown = lv_dropdown_create(wrapper);
if (is_landscape_display) { if (is_landscape_display) {
lv_dropdown_set_options(orientation_dropdown, "Landscape\nLandscape (flipped)\nPortrait Left\nPortrait Right"); lv_dropdown_set_options(orientation_dropdown, "Landscape\nLandscape (flipped)\nPortrait Left\nPortrait Right");
} else { } else {

View File

@ -252,10 +252,10 @@ void View::update() {
void View::init(lv_obj_t* parent) { void View::init(lv_obj_t* parent) {
lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_COLUMN);
lv_obj_t* toolbar = lvgl::toolbar_create(parent, "Files"); auto* toolbar = lvgl::toolbar_create(parent, "Files");
navigate_up_button = lvgl::toolbar_add_button_action(toolbar, LV_SYMBOL_UP, &onNavigateUpPressedCallback, this); navigate_up_button = lvgl::toolbar_add_button_action(toolbar, LV_SYMBOL_UP, &onNavigateUpPressedCallback, this);
lv_obj_t* wrapper = lv_obj_create(parent); auto* wrapper = lv_obj_create(parent);
lv_obj_set_width(wrapper, LV_PCT(100)); lv_obj_set_width(wrapper, LV_PCT(100));
lv_obj_set_style_border_width(wrapper, 0, 0); lv_obj_set_style_border_width(wrapper, 0, 0);
lv_obj_set_style_pad_all(wrapper, 0, 0); lv_obj_set_style_pad_all(wrapper, 0, 0);

View File

@ -25,14 +25,6 @@ private:
public: public:
void lock() const {
tt_check(mutex.lock(1000));
}
void unlock() const {
tt_check(mutex.unlock());
}
void onShow(AppContext& app, lv_obj_t* parent) override; void onShow(AppContext& app, lv_obj_t* parent) override;
void onHide(AppContext& app) override; void onHide(AppContext& app) override;
@ -44,7 +36,7 @@ public:
}; };
void GpioApp::updatePinStates() { void GpioApp::updatePinStates() {
lock(); mutex.lock();
// Update pin states // Update pin states
for (int i = 0; i < GPIO_NUM_MAX; ++i) { for (int i = 0; i < GPIO_NUM_MAX; ++i) {
#ifdef ESP_PLATFORM #ifdef ESP_PLATFORM
@ -53,12 +45,13 @@ void GpioApp::updatePinStates() {
pinStates[i] = gpio_get_level(i); pinStates[i] = gpio_get_level(i);
#endif #endif
} }
unlock(); mutex.unlock();
} }
void GpioApp::updatePinWidgets() { void GpioApp::updatePinWidgets() {
if (lvgl::lock(100)) { auto scoped_lvgl_lock = lvgl::getLvglSyncLockable()->scoped();
lock(); auto scoped_gpio_lock = mutex.scoped();
if (scoped_gpio_lock->lock() && scoped_lvgl_lock->lock(100)) {
for (int j = 0; j < GPIO_NUM_MAX; ++j) { for (int j = 0; j < GPIO_NUM_MAX; ++j) {
int level = pinStates[j]; int level = pinStates[j];
lv_obj_t* label = lvPins[j]; lv_obj_t* label = lvPins[j];
@ -73,8 +66,6 @@ void GpioApp::updatePinWidgets() {
} }
} }
} }
lvgl::unlock();
unlock();
} }
} }
@ -100,14 +91,14 @@ void GpioApp::onTimer(TT_UNUSED std::shared_ptr<void> context) {
} }
void GpioApp::startTask() { void GpioApp::startTask() {
lock(); mutex.lock();
assert(timer == nullptr); assert(timer == nullptr);
timer = std::make_unique<Timer>( timer = std::make_unique<Timer>(
Timer::Type::Periodic, Timer::Type::Periodic,
&onTimer &onTimer
); );
timer->start(100 / portTICK_PERIOD_MS); timer->start(100 / portTICK_PERIOD_MS);
unlock(); mutex.unlock();
} }
void GpioApp::stopTask() { void GpioApp::stopTask() {
@ -122,11 +113,11 @@ void GpioApp::stopTask() {
void GpioApp::onShow(AppContext& app, lv_obj_t* parent) { void GpioApp::onShow(AppContext& app, lv_obj_t* parent) {
lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_COLUMN);
lv_obj_t* toolbar = lvgl::toolbar_create(parent, app); auto* toolbar = lvgl::toolbar_create(parent, app);
lv_obj_align(toolbar, LV_ALIGN_TOP_MID, 0, 0); lv_obj_align(toolbar, LV_ALIGN_TOP_MID, 0, 0);
// Main content wrapper, enables scrolling content without scrolling the toolbar // Main content wrapper, enables scrolling content without scrolling the toolbar
lv_obj_t* wrapper = lv_obj_create(parent); auto* wrapper = lv_obj_create(parent);
lv_obj_set_width(wrapper, LV_PCT(100)); lv_obj_set_width(wrapper, LV_PCT(100));
lv_obj_set_flex_grow(wrapper, 1); lv_obj_set_flex_grow(wrapper, 1);
lv_obj_set_style_border_width(wrapper, 0, 0); lv_obj_set_style_border_width(wrapper, 0, 0);
@ -140,20 +131,20 @@ void GpioApp::onShow(AppContext& app, lv_obj_t* parent) {
uint8_t column = 0; uint8_t column = 0;
uint8_t column_limit = is_landscape_display ? 10 : 5; uint8_t column_limit = is_landscape_display ? 10 : 5;
lv_obj_t* row_wrapper = createGpioRowWrapper(wrapper); auto* row_wrapper = createGpioRowWrapper(wrapper);
lv_obj_align(row_wrapper, LV_ALIGN_TOP_MID, 0, 0); lv_obj_align(row_wrapper, LV_ALIGN_TOP_MID, 0, 0);
lock(); mutex.lock();
for (int i = GPIO_NUM_MIN; i < GPIO_NUM_MAX; ++i) { for (int i = GPIO_NUM_MIN; i < GPIO_NUM_MAX; ++i) {
// Add the GPIO number before the first item on a row // Add the GPIO number before the first item on a row
if (column == 0) { if (column == 0) {
lv_obj_t* prefix = lv_label_create(row_wrapper); auto* prefix = lv_label_create(row_wrapper);
lv_label_set_text_fmt(prefix, "%02d", i); lv_label_set_text_fmt(prefix, "%02d", i);
} }
// Add a new GPIO status indicator // Add a new GPIO status indicator
lv_obj_t* status_label = lv_label_create(row_wrapper); auto* status_label = lv_label_create(row_wrapper);
lv_obj_set_pos(status_label, (int32_t)((column+1) * x_spacing), 0); lv_obj_set_pos(status_label, (int32_t)((column+1) * x_spacing), 0);
lv_label_set_text_fmt(status_label, "%s", LV_SYMBOL_STOP); lv_label_set_text_fmt(status_label, "%s", LV_SYMBOL_STOP);
lvPins[i] = status_label; lvPins[i] = status_label;
@ -162,19 +153,19 @@ void GpioApp::onShow(AppContext& app, lv_obj_t* parent) {
if (column >= column_limit) { if (column >= column_limit) {
// Add the GPIO number after the last item on a row // Add the GPIO number after the last item on a row
lv_obj_t* postfix = lv_label_create(row_wrapper); auto* postfix = lv_label_create(row_wrapper);
lv_label_set_text_fmt(postfix, "%02d", i); lv_label_set_text_fmt(postfix, "%02d", i);
lv_obj_set_pos(postfix, (int32_t)((column+1) * x_spacing), 0); lv_obj_set_pos(postfix, (int32_t)((column+1) * x_spacing), 0);
// Add a new row wrapper underneath the last one // Add a new row wrapper underneath the last one
lv_obj_t* new_row_wrapper = createGpioRowWrapper(wrapper); auto* new_row_wrapper = createGpioRowWrapper(wrapper);
lv_obj_align_to(new_row_wrapper, row_wrapper, LV_ALIGN_BOTTOM_LEFT, 0, 4); lv_obj_align_to(new_row_wrapper, row_wrapper, LV_ALIGN_BOTTOM_LEFT, 0, 4);
row_wrapper = new_row_wrapper; row_wrapper = new_row_wrapper;
column = 0; column = 0;
} }
} }
unlock(); mutex.unlock();
startTask(); startTask();
} }

View File

@ -29,19 +29,19 @@ static void onSwitchToggled(lv_event_t* event) {
} }
static void show(lv_obj_t* parent, const hal::i2c::Configuration& configuration) { static void show(lv_obj_t* parent, const hal::i2c::Configuration& configuration) {
lv_obj_t* card = lv_obj_create(parent); auto* card = lv_obj_create(parent);
lv_obj_set_height(card, LV_SIZE_CONTENT); lv_obj_set_height(card, LV_SIZE_CONTENT);
lv_obj_set_style_margin_hor(card, 16, 0); lv_obj_set_style_margin_hor(card, 16, 0);
lv_obj_set_style_margin_bottom(card, 16, 0); lv_obj_set_style_margin_bottom(card, 16, 0);
lv_obj_set_width(card, LV_PCT(100)); lv_obj_set_width(card, LV_PCT(100));
lv_obj_t* port_label = lv_label_create(card); auto* port_label = lv_label_create(card);
const char* name = configuration.name.empty() ? "Unnamed" : configuration.name.c_str(); const char* name = configuration.name.empty() ? "Unnamed" : configuration.name.c_str();
lv_label_set_text_fmt(port_label, "%s (port %d)", name, configuration.port); lv_label_set_text_fmt(port_label, "%s (port %d)", name, configuration.port);
// On-off switch // On-off switch
if (configuration.canReinit) { if (configuration.canReinit) {
lv_obj_t* state_switch = lv_switch_create(card); auto* state_switch = lv_switch_create(card);
lv_obj_align(state_switch, LV_ALIGN_TOP_RIGHT, 0, 0); lv_obj_align(state_switch, LV_ALIGN_TOP_RIGHT, 0, 0);
if (hal::i2c::isStarted(configuration.port)) { if (hal::i2c::isStarted(configuration.port)) {
@ -52,20 +52,20 @@ static void show(lv_obj_t* parent, const hal::i2c::Configuration& configuration)
} }
// SDA label // SDA label
lv_obj_t* sda_pin_label = lv_label_create(card); auto* sda_pin_label = lv_label_create(card);
const char* sda_pullup_text = configuration.config.sda_pullup_en ? "yes" : "no"; const char* sda_pullup_text = configuration.config.sda_pullup_en ? "yes" : "no";
lv_label_set_text_fmt(sda_pin_label, "SDA: pin %d, pullup: %s", configuration.config.sda_io_num, sda_pullup_text ); lv_label_set_text_fmt(sda_pin_label, "SDA: pin %d, pullup: %s", configuration.config.sda_io_num, sda_pullup_text );
lv_obj_align_to(sda_pin_label, port_label, LV_ALIGN_OUT_BOTTOM_LEFT, 16, 8); lv_obj_align_to(sda_pin_label, port_label, LV_ALIGN_OUT_BOTTOM_LEFT, 16, 8);
// SCL label // SCL label
lv_obj_t* scl_pin_label = lv_label_create(card); auto* scl_pin_label = lv_label_create(card);
const char* scl_pullup_text = configuration.config.scl_pullup_en ? "yes" : "no"; const char* scl_pullup_text = configuration.config.scl_pullup_en ? "yes" : "no";
lv_label_set_text_fmt(scl_pin_label, "SCL: pin %d, pullup: %s", configuration.config.scl_io_num, scl_pullup_text); lv_label_set_text_fmt(scl_pin_label, "SCL: pin %d, pullup: %s", configuration.config.scl_io_num, scl_pullup_text);
lv_obj_align_to(scl_pin_label, sda_pin_label, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 0); lv_obj_align_to(scl_pin_label, sda_pin_label, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 0);
// Frequency: // Frequency:
if (configuration.config.mode == I2C_MODE_MASTER) { if (configuration.config.mode == I2C_MODE_MASTER) {
lv_obj_t* frequency_label = lv_label_create(card); auto* frequency_label = lv_label_create(card);
lv_label_set_text_fmt(frequency_label, "Frequency: %lu Hz", configuration.config.master.clk_speed); lv_label_set_text_fmt(frequency_label, "Frequency: %lu Hz", configuration.config.master.clk_speed);
lv_obj_align_to(frequency_label, scl_pin_label, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 0); lv_obj_align_to(frequency_label, scl_pin_label, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 0);
} }
@ -77,11 +77,12 @@ class I2cSettingsApp : public App {
lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_COLUMN);
lvgl::toolbar_create(parent, app); lvgl::toolbar_create(parent, app);
lv_obj_t* wrapper = lv_obj_create(parent); auto* wrapper = lv_obj_create(parent);
lv_obj_set_width(wrapper, LV_PCT(100)); lv_obj_set_width(wrapper, LV_PCT(100));
lv_obj_set_flex_grow(wrapper, 1); lv_obj_set_flex_grow(wrapper, 1);
lv_obj_set_flex_flow(wrapper, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_flow(wrapper, LV_FLEX_FLOW_COLUMN);
lvgl::obj_set_style_no_padding(wrapper); lv_obj_set_style_pad_all(wrapper, LV_STATE_DEFAULT, 0);
lv_obj_set_style_pad_gap(wrapper, LV_STATE_DEFAULT, 0);
lvgl::obj_set_style_bg_invisible(wrapper); lvgl::obj_set_style_bg_invisible(wrapper);
for (const auto& configuration: getConfiguration()->hardware->i2c) { for (const auto& configuration: getConfiguration()->hardware->i2c) {

View File

@ -81,6 +81,7 @@ private:
} }
public: public:
void onShow(AppContext& app, lv_obj_t* parent) override { void onShow(AppContext& app, lv_obj_t* parent) override {
auto parameters = app.getParameters(); auto parameters = app.getParameters();
tt_check(parameters != nullptr, "Parameters missing"); tt_check(parameters != nullptr, "Parameters missing");

View File

@ -93,8 +93,8 @@ public:
} }
void onResult(AppContext& app, Result result, std::unique_ptr<Bundle> bundle) override { void onResult(AppContext& app, Result result, std::unique_ptr<Bundle> bundle) override {
auto resultIndex = selectiondialog::getResultIndex(*bundle); if (result == Result::Ok && bundle != nullptr) {
if (result == Result::Ok) { auto resultIndex = selectiondialog::getResultIndex(*bundle);
switch (resultIndex) { switch (resultIndex) {
case 0: case 0:
filterLevel = LogLevel::Verbose; filterLevel = LogLevel::Verbose;
@ -114,9 +114,9 @@ public:
default: default:
break; break;
} }
}
updateViews(); updateViews();
}
} }
}; };

View File

@ -56,7 +56,7 @@ private:
} }
void onListItemSelected(lv_event_t* e) { void onListItemSelected(lv_event_t* e) {
size_t index = reinterpret_cast<std::size_t>(lv_event_get_user_data(e)); auto index = reinterpret_cast<std::size_t>(lv_event_get_user_data(e));
TT_LOG_I(TAG, "Selected item at index %d", index); TT_LOG_I(TAG, "Selected item at index %d", index);
auto bundle = std::make_unique<Bundle>(); auto bundle = std::make_unique<Bundle>();
bundle->putInt32(RESULT_BUNDLE_KEY_INDEX, (int32_t)index); bundle->putInt32(RESULT_BUNDLE_KEY_INDEX, (int32_t)index);
@ -77,7 +77,7 @@ public:
std::string title = getTitleParameter(app.getParameters()); std::string title = getTitleParameter(app.getParameters());
lvgl::toolbar_create(parent, title); lvgl::toolbar_create(parent, title);
lv_obj_t* list = lv_list_create(parent); auto* list = lv_list_create(parent);
lv_obj_set_width(list, LV_PCT(100)); lv_obj_set_width(list, LV_PCT(100));
lv_obj_set_flex_grow(list, 1); lv_obj_set_flex_grow(list, 1);

View File

@ -19,7 +19,7 @@ static void createWidget(const std::shared_ptr<AppManifest>& manifest, void* par
tt_check(parent); tt_check(parent);
auto* list = (lv_obj_t*)parent; auto* list = (lv_obj_t*)parent;
const void* icon = !manifest->icon.empty() ? manifest->icon.c_str() : TT_ASSETS_APP_ICON_FALLBACK; const void* icon = !manifest->icon.empty() ? manifest->icon.c_str() : TT_ASSETS_APP_ICON_FALLBACK;
lv_obj_t* btn = lv_list_add_button(list, icon, manifest->name.c_str()); auto* btn = lv_list_add_button(list, icon, manifest->name.c_str());
lv_obj_add_event_cb(btn, &onAppPressed, LV_EVENT_SHORT_CLICKED, (void*)manifest.get()); lv_obj_add_event_cb(btn, &onAppPressed, LV_EVENT_SHORT_CLICKED, (void*)manifest.get());
} }
@ -30,7 +30,7 @@ class SettingsApp : public App {
lvgl::toolbar_create(parent, app); lvgl::toolbar_create(parent, app);
lv_obj_t* list = lv_list_create(parent); auto* list = lv_list_create(parent);
lv_obj_set_width(list, LV_PCT(100)); lv_obj_set_width(list, LV_PCT(100));
lv_obj_set_flex_grow(list, 1); lv_obj_set_flex_grow(list, 1);

View File

@ -18,14 +18,14 @@ class TextViewerApp : public App {
lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_COLUMN);
lvgl::toolbar_create(parent, app); lvgl::toolbar_create(parent, app);
lv_obj_t* wrapper = lv_obj_create(parent); auto* wrapper = lv_obj_create(parent);
lv_obj_set_width(wrapper, LV_PCT(100)); lv_obj_set_width(wrapper, LV_PCT(100));
lv_obj_set_flex_grow(wrapper, 1); lv_obj_set_flex_grow(wrapper, 1);
lv_obj_set_flex_flow(wrapper, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_flow(wrapper, LV_FLEX_FLOW_COLUMN);
lvgl::obj_set_style_no_padding(wrapper); lv_obj_set_style_pad_all(wrapper, 0, 0);
lvgl::obj_set_style_bg_invisible(wrapper); lvgl::obj_set_style_bg_invisible(wrapper);
lv_obj_t* label = lv_label_create(wrapper); auto* label = lv_label_create(wrapper);
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0); lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
auto parameters = app.getParameters(); auto parameters = app.getParameters();
tt_check(parameters != nullptr, "Parameters missing"); tt_check(parameters != nullptr, "Parameters missing");

View File

@ -89,7 +89,7 @@ public:
} }
void onResult(AppContext& app, Result result, std::unique_ptr<Bundle> bundle) override { void onResult(AppContext& app, Result result, std::unique_ptr<Bundle> bundle) override {
if (result == Result::Ok) { if (result == Result::Ok && bundle != nullptr) {
auto name = timezone::getResultName(*bundle); auto name = timezone::getResultName(*bundle);
auto code = timezone::getResultCode(*bundle); auto code = timezone::getResultCode(*bundle);
TT_LOG_I(TAG, "Result name=%s code=%s", name.c_str(), code.c_str()); TT_LOG_I(TAG, "Result name=%s code=%s", name.c_str(), code.c_str());

View File

@ -115,7 +115,7 @@ private:
} }
static void createListItem(lv_obj_t* list, const std::string& title, size_t index) { static void createListItem(lv_obj_t* list, const std::string& title, size_t index) {
lv_obj_t* btn = lv_list_add_button(list, nullptr, title.c_str()); auto* btn = lv_list_add_button(list, nullptr, title.c_str());
lv_obj_add_event_cb(btn, &onListItemSelectedCallback, LV_EVENT_SHORT_CLICKED, (void*)index); lv_obj_add_event_cb(btn, &onListItemSelectedCallback, LV_EVENT_SHORT_CLICKED, (void*)index);
} }

View File

@ -81,7 +81,7 @@ class WifiApSettings : public App {
// Wrappers // Wrappers
lv_obj_t* wrapper = lv_obj_create(parent); auto* wrapper = lv_obj_create(parent);
lv_obj_set_width(wrapper, LV_PCT(100)); lv_obj_set_width(wrapper, LV_PCT(100));
lv_obj_set_flex_grow(wrapper, 1); lv_obj_set_flex_grow(wrapper, 1);
lv_obj_set_flex_flow(wrapper, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_flow(wrapper, LV_FLEX_FLOW_COLUMN);
@ -89,24 +89,24 @@ class WifiApSettings : public App {
// Auto-connect toggle // Auto-connect toggle
lv_obj_t* auto_connect_wrapper = lv_obj_create(wrapper); auto* auto_connect_wrapper = lv_obj_create(wrapper);
lv_obj_set_size(auto_connect_wrapper, LV_PCT(100), LV_SIZE_CONTENT); lv_obj_set_size(auto_connect_wrapper, LV_PCT(100), LV_SIZE_CONTENT);
lvgl::obj_set_style_no_padding(auto_connect_wrapper); lvgl::obj_set_style_no_padding(auto_connect_wrapper);
lv_obj_set_style_border_width(auto_connect_wrapper, 0, 0); lv_obj_set_style_border_width(auto_connect_wrapper, 0, 0);
lv_obj_t* auto_connect_label = lv_label_create(auto_connect_wrapper); auto* auto_connect_label = lv_label_create(auto_connect_wrapper);
lv_label_set_text(auto_connect_label, "Auto-connect"); lv_label_set_text(auto_connect_label, "Auto-connect");
lv_obj_align(auto_connect_label, LV_ALIGN_TOP_LEFT, 0, 6); lv_obj_align(auto_connect_label, LV_ALIGN_TOP_LEFT, 0, 6);
lv_obj_t* auto_connect_switch = lv_switch_create(auto_connect_wrapper); auto* auto_connect_switch = lv_switch_create(auto_connect_wrapper);
lv_obj_add_event_cb(auto_connect_switch, onToggleAutoConnect, LV_EVENT_VALUE_CHANGED, (void*)&paremeters); lv_obj_add_event_cb(auto_connect_switch, onToggleAutoConnect, LV_EVENT_VALUE_CHANGED, (void*)&paremeters);
lv_obj_align(auto_connect_switch, LV_ALIGN_TOP_RIGHT, 0, 0); lv_obj_align(auto_connect_switch, LV_ALIGN_TOP_RIGHT, 0, 0);
lv_obj_t* forget_button = lv_button_create(wrapper); auto* forget_button = lv_button_create(wrapper);
lv_obj_set_width(forget_button, LV_PCT(100)); lv_obj_set_width(forget_button, LV_PCT(100));
lv_obj_align_to(forget_button, auto_connect_wrapper, LV_ALIGN_OUT_BOTTOM_MID, 0, 10); lv_obj_align_to(forget_button, auto_connect_wrapper, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);
lv_obj_add_event_cb(forget_button, onPressForget, LV_EVENT_SHORT_CLICKED, nullptr); lv_obj_add_event_cb(forget_button, onPressForget, LV_EVENT_SHORT_CLICKED, nullptr);
lv_obj_t* forget_button_label = lv_label_create(forget_button); auto* forget_button_label = lv_label_create(forget_button);
lv_obj_align(forget_button_label, LV_ALIGN_CENTER, 0, 0); lv_obj_align(forget_button_label, LV_ALIGN_CENTER, 0, 0);
lv_label_set_text(forget_button_label, "Forget"); lv_label_set_text(forget_button_label, "Forget");

View File

@ -84,7 +84,7 @@ void View::setLoading(bool loading) {
} }
void View::createBottomButtons(lv_obj_t* parent) { void View::createBottomButtons(lv_obj_t* parent) {
lv_obj_t* button_container = lv_obj_create(parent); auto* button_container = lv_obj_create(parent);
lv_obj_set_width(button_container, LV_PCT(100)); lv_obj_set_width(button_container, LV_PCT(100));
lv_obj_set_height(button_container, LV_SIZE_CONTENT); lv_obj_set_height(button_container, LV_SIZE_CONTENT);
lvgl::obj_set_style_no_padding(button_container); lvgl::obj_set_style_no_padding(button_container);
@ -94,7 +94,7 @@ void View::createBottomButtons(lv_obj_t* parent) {
lv_obj_add_state(remember_switch, LV_STATE_CHECKED); lv_obj_add_state(remember_switch, LV_STATE_CHECKED);
lv_obj_align(remember_switch, LV_ALIGN_LEFT_MID, 0, 0); lv_obj_align(remember_switch, LV_ALIGN_LEFT_MID, 0, 0);
lv_obj_t* remember_label = lv_label_create(button_container); auto* remember_label = lv_label_create(button_container);
lv_label_set_text(remember_label, "Remember"); lv_label_set_text(remember_label, "Remember");
lv_obj_align(remember_label, LV_ALIGN_CENTER, 0, 0); lv_obj_align(remember_label, LV_ALIGN_CENTER, 0, 0);
lv_obj_align_to(remember_label, remember_switch, LV_ALIGN_OUT_RIGHT_MID, 4, 0); lv_obj_align_to(remember_label, remember_switch, LV_ALIGN_OUT_RIGHT_MID, 4, 0);
@ -104,7 +104,7 @@ void View::createBottomButtons(lv_obj_t* parent) {
lv_obj_add_flag(connecting_spinner, LV_OBJ_FLAG_HIDDEN); lv_obj_add_flag(connecting_spinner, LV_OBJ_FLAG_HIDDEN);
connect_button = lv_btn_create(button_container); connect_button = lv_btn_create(button_container);
lv_obj_t* connect_label = lv_label_create(connect_button); auto* connect_label = lv_label_create(connect_button);
lv_label_set_text(connect_label, "Connect"); lv_label_set_text(connect_label, "Connect");
lv_obj_align(connect_button, LV_ALIGN_RIGHT_MID, 0, 0); lv_obj_align(connect_button, LV_ALIGN_RIGHT_MID, 0, 0);
lv_obj_add_event_cb(connect_button, &onConnect, LV_EVENT_SHORT_CLICKED, nullptr); lv_obj_add_event_cb(connect_button, &onConnect, LV_EVENT_SHORT_CLICKED, nullptr);
@ -116,20 +116,20 @@ void View::init(AppContext& app, lv_obj_t* parent) {
lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_COLUMN);
lvgl::toolbar_create(parent, app); lvgl::toolbar_create(parent, app);
lv_obj_t* wrapper = lv_obj_create(parent); auto* wrapper = lv_obj_create(parent);
lv_obj_set_width(wrapper, LV_PCT(100)); lv_obj_set_width(wrapper, LV_PCT(100));
lv_obj_set_flex_grow(wrapper, 1); lv_obj_set_flex_grow(wrapper, 1);
lv_obj_set_flex_flow(wrapper, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_flow(wrapper, LV_FLEX_FLOW_COLUMN);
// SSID // SSID
lv_obj_t* ssid_wrapper = lv_obj_create(wrapper); auto* ssid_wrapper = lv_obj_create(wrapper);
lv_obj_set_width(ssid_wrapper, LV_PCT(100)); lv_obj_set_width(ssid_wrapper, LV_PCT(100));
lv_obj_set_height(ssid_wrapper, LV_SIZE_CONTENT); lv_obj_set_height(ssid_wrapper, LV_SIZE_CONTENT);
lvgl::obj_set_style_no_padding(ssid_wrapper); lvgl::obj_set_style_no_padding(ssid_wrapper);
lv_obj_set_style_border_width(ssid_wrapper, 0, 0); lv_obj_set_style_border_width(ssid_wrapper, 0, 0);
lv_obj_t* ssid_label_wrapper = lv_obj_create(ssid_wrapper); auto* ssid_label_wrapper = lv_obj_create(ssid_wrapper);
lv_obj_set_width(ssid_label_wrapper, LV_PCT(50)); lv_obj_set_width(ssid_label_wrapper, LV_PCT(50));
lv_obj_set_height(ssid_label_wrapper, LV_SIZE_CONTENT); lv_obj_set_height(ssid_label_wrapper, LV_SIZE_CONTENT);
lv_obj_align(ssid_label_wrapper, LV_ALIGN_LEFT_MID, 0, 0); lv_obj_align(ssid_label_wrapper, LV_ALIGN_LEFT_MID, 0, 0);
@ -137,7 +137,7 @@ void View::init(AppContext& app, lv_obj_t* parent) {
lv_obj_set_style_pad_left(ssid_label_wrapper, 0, 0); lv_obj_set_style_pad_left(ssid_label_wrapper, 0, 0);
lv_obj_set_style_pad_right(ssid_label_wrapper, 0, 0); lv_obj_set_style_pad_right(ssid_label_wrapper, 0, 0);
lv_obj_t* ssid_label = lv_label_create(ssid_label_wrapper); auto* ssid_label = lv_label_create(ssid_label_wrapper);
lv_label_set_text(ssid_label, "Network:"); lv_label_set_text(ssid_label, "Network:");
ssid_textarea = lv_textarea_create(ssid_wrapper); ssid_textarea = lv_textarea_create(ssid_wrapper);
@ -151,13 +151,13 @@ void View::init(AppContext& app, lv_obj_t* parent) {
// Password // Password
lv_obj_t* password_wrapper = lv_obj_create(wrapper); auto* password_wrapper = lv_obj_create(wrapper);
lv_obj_set_width(password_wrapper, LV_PCT(100)); lv_obj_set_width(password_wrapper, LV_PCT(100));
lv_obj_set_height(password_wrapper, LV_SIZE_CONTENT); lv_obj_set_height(password_wrapper, LV_SIZE_CONTENT);
lvgl::obj_set_style_no_padding(password_wrapper); lvgl::obj_set_style_no_padding(password_wrapper);
lv_obj_set_style_border_width(password_wrapper, 0, 0); lv_obj_set_style_border_width(password_wrapper, 0, 0);
lv_obj_t* password_label_wrapper = lv_obj_create(password_wrapper); auto* password_label_wrapper = lv_obj_create(password_wrapper);
lv_obj_set_width(password_label_wrapper, LV_PCT(50)); lv_obj_set_width(password_label_wrapper, LV_PCT(50));
lv_obj_set_height(password_label_wrapper, LV_SIZE_CONTENT); lv_obj_set_height(password_label_wrapper, LV_SIZE_CONTENT);
lv_obj_align_to(password_label_wrapper, password_wrapper, LV_ALIGN_LEFT_MID, 0, 0); lv_obj_align_to(password_label_wrapper, password_wrapper, LV_ALIGN_LEFT_MID, 0, 0);
@ -165,7 +165,7 @@ void View::init(AppContext& app, lv_obj_t* parent) {
lv_obj_set_style_pad_left(password_label_wrapper, 0, 0); lv_obj_set_style_pad_left(password_label_wrapper, 0, 0);
lv_obj_set_style_pad_right(password_label_wrapper, 0, 0); lv_obj_set_style_pad_right(password_label_wrapper, 0, 0);
lv_obj_t* password_label = lv_label_create(password_label_wrapper); auto* password_label = lv_label_create(password_label_wrapper);
lv_label_set_text(password_label, "Password:"); lv_label_set_text(password_label, "Password:");
password_textarea = lv_textarea_create(password_wrapper); password_textarea = lv_textarea_create(password_wrapper);

View File

@ -60,9 +60,9 @@ static void onConnectToHiddenClicked(lv_event_t* event) {
// region Secondary updates // region Secondary updates
static void connect(lv_event_t* event) { static void connect(lv_event_t* event) {
lv_obj_t* wrapper = lv_event_get_current_target_obj(event); auto* wrapper = lv_event_get_current_target_obj(event);
// Assumes that the second child of the button is a label ... risky // Assumes that the second child of the button is a label ... risky
lv_obj_t* label = lv_obj_get_child(wrapper, 0); auto* label = lv_obj_get_child(wrapper, 0);
// We get the SSID from the button label because it's safer than alloc'ing // We get the SSID from the button label because it's safer than alloc'ing
// our own and passing it as the event data // our own and passing it as the event data
const char* ssid = lv_label_get_text(label); const char* ssid = lv_label_get_text(label);
@ -74,16 +74,16 @@ static void connect(lv_event_t* event) {
} }
static void showDetails(lv_event_t* event) { static void showDetails(lv_event_t* event) {
lv_obj_t* wrapper = lv_event_get_current_target_obj(event); auto* wrapper = lv_event_get_current_target_obj(event);
// Hack: Get the hidden label with the ssid // Hack: Get the hidden label with the ssid
lv_obj_t* ssid_label = lv_obj_get_child(wrapper, 1); auto* ssid_label = lv_obj_get_child(wrapper, 1);
const char* ssid = lv_label_get_text(ssid_label); const char* ssid = lv_label_get_text(ssid_label);
auto* bindings = (Bindings*)lv_event_get_user_data(event); auto* bindings = (Bindings*)lv_event_get_user_data(event);
bindings->onShowApSettings(ssid); bindings->onShowApSettings(ssid);
} }
void View::createSsidListItem(const service::wifi::ApRecord& record, bool isConnecting) { void View::createSsidListItem(const service::wifi::ApRecord& record, bool isConnecting) {
lv_obj_t* wrapper = lv_obj_create(networks_list); auto* wrapper = lv_obj_create(networks_list);
lv_obj_add_event_cb(wrapper, &connect, LV_EVENT_SHORT_CLICKED, bindings); lv_obj_add_event_cb(wrapper, &connect, LV_EVENT_SHORT_CLICKED, bindings);
lv_obj_set_user_data(wrapper, bindings); lv_obj_set_user_data(wrapper, bindings);
lv_obj_set_size(wrapper, LV_PCT(100), LV_SIZE_CONTENT); lv_obj_set_size(wrapper, LV_PCT(100), LV_SIZE_CONTENT);
@ -91,13 +91,13 @@ void View::createSsidListItem(const service::wifi::ApRecord& record, bool isConn
lv_obj_set_style_margin_all(wrapper, 0, 0); lv_obj_set_style_margin_all(wrapper, 0, 0);
lv_obj_set_style_border_width(wrapper, 0, 0); lv_obj_set_style_border_width(wrapper, 0, 0);
lv_obj_t* label = lv_label_create(wrapper); auto* label = lv_label_create(wrapper);
lv_obj_align(label, LV_ALIGN_LEFT_MID, 0, 0); lv_obj_align(label, LV_ALIGN_LEFT_MID, 0, 0);
lv_label_set_text(label, record.ssid.c_str()); lv_label_set_text(label, record.ssid.c_str());
lv_label_set_long_mode(label, LV_LABEL_LONG_SCROLL_CIRCULAR); lv_label_set_long_mode(label, LV_LABEL_LONG_SCROLL_CIRCULAR);
lv_obj_set_width(label, LV_PCT(70)); lv_obj_set_width(label, LV_PCT(70));
lv_obj_t* info_wrapper = lv_obj_create(wrapper); auto* info_wrapper = lv_obj_create(wrapper);
lv_obj_set_style_pad_all(info_wrapper, 0, 0); lv_obj_set_style_pad_all(info_wrapper, 0, 0);
lv_obj_set_style_margin_all(info_wrapper, 0, 0); lv_obj_set_style_margin_all(info_wrapper, 0, 0);
lv_obj_set_size(info_wrapper, 36, 36); lv_obj_set_size(info_wrapper, 36, 36);
@ -105,17 +105,17 @@ void View::createSsidListItem(const service::wifi::ApRecord& record, bool isConn
lv_obj_add_event_cb(info_wrapper, &showDetails, LV_EVENT_SHORT_CLICKED, bindings); lv_obj_add_event_cb(info_wrapper, &showDetails, LV_EVENT_SHORT_CLICKED, bindings);
lv_obj_align(info_wrapper, LV_ALIGN_RIGHT_MID, 0, 0); lv_obj_align(info_wrapper, LV_ALIGN_RIGHT_MID, 0, 0);
lv_obj_t* info_label = lv_label_create(info_wrapper); auto* info_label = lv_label_create(info_wrapper);
lv_label_set_text(info_label, "i"); lv_label_set_text(info_label, "i");
// Hack: Create a hidden label to store data and pass it to the callback // Hack: Create a hidden label to store data and pass it to the callback
lv_obj_t* ssid_label = lv_label_create(info_wrapper); auto* ssid_label = lv_label_create(info_wrapper);
lv_label_set_text(ssid_label, record.ssid.c_str()); lv_label_set_text(ssid_label, record.ssid.c_str());
lv_obj_add_flag(ssid_label, LV_OBJ_FLAG_HIDDEN); lv_obj_add_flag(ssid_label, LV_OBJ_FLAG_HIDDEN);
lv_obj_set_style_text_color(info_label, lv_theme_get_color_primary(info_wrapper), 0); lv_obj_set_style_text_color(info_label, lv_theme_get_color_primary(info_wrapper), 0);
lv_obj_align(info_label, LV_ALIGN_CENTER, 0, 0); lv_obj_align(info_label, LV_ALIGN_CENTER, 0, 0);
if (isConnecting) { if (isConnecting) {
lv_obj_t* connecting_spinner = tt::lvgl::spinner_create(wrapper); auto* connecting_spinner = tt::lvgl::spinner_create(wrapper);
lv_obj_align_to(connecting_spinner, info_wrapper, LV_ALIGN_OUT_LEFT_MID, -8, 0); lv_obj_align_to(connecting_spinner, info_wrapper, LV_ALIGN_OUT_LEFT_MID, -8, 0);
} else { } else {
auto percentage = mapRssiToPercentage(record.rssi); auto percentage = mapRssiToPercentage(record.rssi);
@ -127,8 +127,8 @@ void View::createSsidListItem(const service::wifi::ApRecord& record, bool isConn
auth_info = ""; auth_info = "";
} }
std::string info = std::format("{}{}%", auth_info, percentage); auto info = std::format("{}{}%", auth_info, percentage);
lv_obj_t* open_label = lv_label_create(wrapper); auto* open_label = lv_label_create(wrapper);
lv_label_set_text(open_label, info.c_str()); lv_label_set_text(open_label, info.c_str());
lv_obj_align(open_label, LV_ALIGN_RIGHT_MID, -42, 0); lv_obj_align(open_label, LV_ALIGN_RIGHT_MID, -42, 0);
} }

View File

@ -1,8 +1,8 @@
#include "Tactility/app/display/DisplaySettings.h" #include "Tactility/app/display/DisplaySettings.h"
#include "Tactility/lvgl/LvglKeypad.h" #include "Tactility/lvgl/LvglKeypad.h"
#include "Tactility/lvgl/LvglDisplay.h"
#include <Tactility/hal/Configuration.h> #include <Tactility/hal/Configuration.h>
#include <Tactility/hal/Display.h>
#include <Tactility/hal/Keyboard.h> #include <Tactility/hal/Keyboard.h>
#include <Tactility/hal/Touch.h> #include <Tactility/hal/Touch.h>
#include <Tactility/kernel/SystemEvents.h> #include <Tactility/kernel/SystemEvents.h>

View File

@ -1,15 +0,0 @@
#include "Tactility/lvgl/LvglDisplay.h"
#include <Tactility/Check.h>
namespace tt::lvgl {
hal::Display* getDisplay() {
auto* lvgl_display = lv_display_get_default();
assert(lvgl_display != nullptr);
auto* hal_display = (tt::hal::Display*)lv_display_get_user_data(lvgl_display);
assert(hal_display != nullptr);
return hal_display;
}
}

View File

@ -13,15 +13,8 @@ void obj_set_style_bg_invisible(lv_obj_t* obj) {
} }
void obj_set_style_no_padding(lv_obj_t* obj) { void obj_set_style_no_padding(lv_obj_t* obj) {
lv_obj_set_style_pad_all(obj, LV_STATE_DEFAULT, 0); lv_obj_set_style_pad_all(obj, 0, 0);
lv_obj_set_style_pad_gap(obj, LV_STATE_DEFAULT, 0); lv_obj_set_style_pad_gap(obj, 0, 0);
}
void obj_set_style_auto_padding(lv_obj_t* obj) {
lv_obj_set_style_pad_top(obj, 8, 0);
lv_obj_set_style_pad_bottom(obj, 8, 0);
lv_obj_set_style_pad_left(obj, 16, 0);
lv_obj_set_style_pad_right(obj, 16, 0);
} }
} // namespace } // namespace