Fixes and improvements (#642)

This commit is contained in:
Shadowtrance
2026-08-31 07:10:52 +10:00
committed by GitHub
parent 7a81b525ed
commit d3656bcd3d
14 changed files with 344 additions and 73 deletions
+7 -6
View File
@@ -53,17 +53,18 @@ void collectManifest(const ::AppManifest* manifest, void* context) {
void createWidgets(lv_obj_t* parent, void* userData) {
auto* ctx = static_cast<Context*>(userData);
// Flex column + flex_grow so LVGL recomputes the toolbar/list split on every layout pass,
// rather than a fixed height computed once from lv_obj_get_content_height(parent) that would
// go stale after a later display resolution/rotation change.
lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_COLUMN);
lv_obj_set_style_pad_row(parent, 0, LV_STATE_DEFAULT);
auto* toolbar = lvgl_toolbar_create(parent, "Apps");
lvgl_toolbar_set_nav_action(toolbar, LV_SYMBOL_CLOSE, onBackPressed, ctx);
lv_obj_align(toolbar, LV_ALIGN_TOP_MID, 0, 0);
lv_obj_t* list = lv_list_create(parent);
lv_obj_set_width(list, LV_PCT(100));
lv_obj_align_to(list, toolbar, LV_ALIGN_OUT_BOTTOM_MID, 0, 0);
auto toolbar_height = lv_obj_get_height(toolbar);
auto parent_content_height = lv_obj_get_content_height(parent);
lv_obj_set_height(list, parent_content_height - toolbar_height);
lv_obj_set_flex_grow(list, 1);
std::vector<const ::AppManifest*> manifests;
app_manager_for_each_manifest(collectManifest, &manifests);
@@ -55,18 +55,18 @@ void collectManifest(const ::AppManifest* manifest, void* context) {
void createWidgets(lv_obj_t* parent, void* userData) {
auto* ctx = static_cast<Context*>(userData);
// Flex column + flex_grow; see AppList.cpp's createWidgets() for why a fixed height computed
// once from lv_obj_get_content_height(parent) goes stale.
lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_COLUMN);
lv_obj_set_style_pad_row(parent, 0, LV_STATE_DEFAULT);
auto* toolbar = lvgl_toolbar_create(parent, "Installed Apps");
// The global toolbar nav callback only knows how to stop old-model apps.
lvgl_toolbar_set_nav_action(toolbar, LV_SYMBOL_CLOSE, onBackPressed, ctx);
lv_obj_align(toolbar, LV_ALIGN_TOP_MID, 0, 0);
lv_obj_t* list = lv_list_create(parent);
lv_obj_set_width(list, LV_PCT(100));
lv_obj_align_to(list, toolbar, LV_ALIGN_OUT_BOTTOM_MID, 0, 0);
auto toolbar_height = lv_obj_get_height(toolbar);
auto parent_content_height = lv_obj_get_content_height(parent);
lv_obj_set_height(list, parent_content_height - toolbar_height);
lv_obj_set_flex_grow(list, 1);
std::vector<const ::AppManifest*> manifests;
app_manager_for_each_manifest(collectManifest, &manifests);
@@ -83,9 +83,20 @@ void createWidgets(lv_obj_t* parent, void* userData) {
}
if (app_count == 0) {
auto* no_apps_label = lv_label_create(parent);
// lv_obj_align() is ignored for children of a flex-managed parent, so the empty-state
// label needs its own flex-growing wrapper to center within; the (empty) list is hidden
// rather than deleted so the wrapper can just take its place in the flex flow.
lv_obj_add_flag(list, LV_OBJ_FLAG_HIDDEN);
lv_obj_set_flex_grow(list, 0);
auto* empty_wrapper = lv_obj_create(parent);
lv_obj_set_width(empty_wrapper, LV_PCT(100));
lv_obj_set_flex_grow(empty_wrapper, 1);
lv_obj_set_flex_align(empty_wrapper, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
lv_obj_set_style_border_width(empty_wrapper, 0, LV_STATE_DEFAULT);
auto* no_apps_label = lv_label_create(empty_wrapper);
lv_label_set_text(no_apps_label, "No apps installed");
lv_obj_align(no_apps_label, LV_ALIGN_CENTER, 0, 0);
}
}
@@ -31,6 +31,7 @@
#include <sdkconfig.h>
#include <algorithm>
#include <iomanip>
#include <memory>
#include <sstream>
@@ -178,12 +179,11 @@ void createWidgets(lv_obj_t* parent, void* userData) {
int32_t available_height = parent_height - top_label_height - bottom_label_height;
int32_t available_width = lv_display_get_horizontal_resolution(display);
int32_t smallest_size = std::min(available_height, available_width);
int32_t pixel_size;
if (qrcode.size * 2 <= smallest_size) {
pixel_size = 2;
} else if (qrcode.size <= smallest_size) {
pixel_size = 1;
} else {
// Target ~60% of the available space so the code scales with screen size but keeps a margin
// from the labels/screen edges.
int32_t target_size = smallest_size * 6 / 10;
int32_t pixel_size = std::max<int32_t>(1, target_size / qrcode.size);
if (pixel_size * qrcode.size > smallest_size) {
LOG_E(TAG, "QR code won't fit screen");
ctx->hasFatalError = true;
return;