Add custom icon fonts to lvgl-module (#499)

* **New Features**
  * Added Material Design symbol fonts and LVGL font aliases for launcher, status bar, and shared UI icons.

* **Style**
  * Migrated app icons across the UI to the new symbol font system.
  * Updated launcher button sizing, font styling, recoloring and icon text color for consistency.
  * Default text/icon font macros set for consistent sizing across the UI.

* **Documentation**
  * Updated third‑party notices to include Material Design Icons links.
This commit is contained in:
Ken Van Hoeylandt
2026-02-13 20:27:08 +01:00
committed by GitHub
parent 4ab29ae466
commit 72c9b2b113
53 changed files with 1356 additions and 79 deletions
+2 -1
View File
@@ -10,6 +10,7 @@
#include "tactility/drivers/uart_controller.h"
#include <cstring>
#include <lvgl.h>
#include <tactility/lvgl_symbols_shared.h>
namespace tt::app::addgps {
@@ -193,7 +194,7 @@ public:
extern const AppManifest manifest = {
.appId = "AddGps",
.appName = "Add GPS",
.appIcon = LV_SYMBOL_GPS,
.appIcon = LVGL_SYMBOL_NAVIGATION,
.appCategory = Category::System,
.appFlags = AppManifest::Flags::Hidden,
.createApp = create<AddGpsApp>
@@ -12,6 +12,7 @@
#include <Tactility/service/wifi/Wifi.h>
#include <lvgl.h>
#include <tactility/lvgl_symbols_shared.h>
#include <algorithm>
#include <format>
@@ -178,6 +179,7 @@ public:
extern const AppManifest manifest = {
.appId = "AppHub",
.appName = "App Hub",
.appIcon = LVGL_SYMBOL_HUB,
.appCategory = Category::System,
.createApp = create<AppHubApp>,
};
+6 -3
View File
@@ -2,11 +2,12 @@
#include <Tactility/service/loader/Loader.h>
#include <Tactility/lvgl/Toolbar.h>
#include <Tactility/Assets.h>
#include <lvgl.h>
#include <algorithm>
#include <tactility/lvgl_fonts.h>
#include <tactility/lvgl_symbols_shared.h>
namespace tt::app::applist {
class AppListApp final : public App {
@@ -17,8 +18,10 @@ class AppListApp final : public App {
}
static void createAppWidget(const std::shared_ptr<AppManifest>& manifest, lv_obj_t* list) {
const void* icon = !manifest->appIcon.empty() ? manifest->appIcon.c_str() : TT_ASSETS_APP_ICON_FALLBACK;
const void* icon = !manifest->appIcon.empty() ? manifest->appIcon.c_str() : LVGL_SYMBOL_TOOLBAR;
lv_obj_t* btn = lv_list_add_button(list, icon, manifest->appName.c_str());
lv_obj_t* image = lv_obj_get_child(btn, 0);
lv_obj_set_style_text_font(image, LVGL_SYMBOL_FONT_DEFAULT, LV_PART_MAIN);
lv_obj_add_event_cb(btn, &onAppPressed, LV_EVENT_SHORT_CLICKED, manifest.get());
}
@@ -1,9 +1,10 @@
#include <Tactility/app/appdetails/AppDetails.h>
#include <Tactility/app/AppRegistration.h>
#include <Tactility/service/loader/Loader.h>
#include <Tactility/lvgl/Toolbar.h>
#include <tactility/lvgl_fonts.h>
#include <tactility/lvgl_symbols_shared.h>
#include <Tactility/Assets.h>
#include <Tactility/app/AppRegistration.h>
#include <Tactility/app/appdetails/AppDetails.h>
#include <Tactility/lvgl/Toolbar.h>
#include <Tactility/service/loader/Loader.h>
#include <lvgl.h>
#include <algorithm>
@@ -18,8 +19,10 @@ class AppSettingsApp final : public App {
}
static void createAppWidget(const std::shared_ptr<AppManifest>& manifest, lv_obj_t* list) {
const void* icon = !manifest->appIcon.empty() ? manifest->appIcon.c_str() : TT_ASSETS_APP_ICON_FALLBACK;
const void* icon = !manifest->appIcon.empty() ? manifest->appIcon.c_str() : LVGL_SYMBOL_TOOLBAR;
lv_obj_t* btn = lv_list_add_button(list, icon, manifest->appName.c_str());
lv_obj_t* image = lv_obj_get_child(btn, 0);
lv_obj_set_style_text_font(image, LVGL_SYMBOL_FONT_DEFAULT, LV_PART_MAIN);
lv_obj_add_event_cb(btn, &onAppPressed, LV_EVENT_SHORT_CLICKED, manifest.get());
}
@@ -59,6 +62,7 @@ public:
extern const AppManifest manifest = {
.appId = "AppSettings",
.appName = "Apps",
.appIcon = LVGL_SYMBOL_APPS,
.appCategory = Category::Settings,
.createApp = create<AppSettingsApp>,
};
+2 -2
View File
@@ -8,13 +8,13 @@
#include <Tactility/app/chat/ChatProtocol.h>
#include <Tactility/app/AppManifest.h>
#include <Tactility/Assets.h>
#include <Tactility/Logger.h>
#include <Tactility/lvgl/LvglSync.h>
#include <algorithm>
#include <cctype>
#include <cstdlib>
#include <tactility/lvgl_symbols_shared.h>
#include <vector>
namespace tt::app::chat {
@@ -181,7 +181,7 @@ void ChatApp::switchChannel(const std::string& chatChannel) {
extern const AppManifest manifest = {
.appId = "Chat",
.appName = "Chat",
.appIcon = TT_ASSETS_APP_ICON_CHAT,
.appIcon = LVGL_SYMBOL_FORUM,
.createApp = create<ChatApp>
};
@@ -13,6 +13,8 @@
#include <Tactility/service/loader/Loader.h>
#include <Tactility/service/wifi/Wifi.h>
#include <tactility/lvgl_symbols_shared.h>
#include <cstring>
#include <lvgl.h>
@@ -163,6 +165,7 @@ public:
extern const AppManifest manifest = {
.appId = "Development",
.appName = "Development",
.appIcon = LVGL_SYMBOL_DEVICES,
.appCategory = Category::Settings,
.createApp = create<DevelopmentApp>
};
+6 -4
View File
@@ -1,13 +1,15 @@
#include <Tactility/Tactility.h>
#include <tactility/lvgl_symbols_shared.h>
#ifdef ESP_PLATFORM
#include <Tactility/service/displayidle/DisplayIdleService.h>
#endif
#include <Tactility/settings/DisplaySettings.h>
#include <Tactility/Assets.h>
#include <Tactility/hal/display/DisplayDevice.h>
#include <Tactility/Logger.h>
#include <Tactility/hal/display/DisplayDevice.h>
#include <Tactility/lvgl/Toolbar.h>
#include <Tactility/settings/DisplaySettings.h>
#include <lvgl.h>
@@ -304,7 +306,7 @@ public:
extern const AppManifest manifest = {
.appId = "Display",
.appName = "Display",
.appIcon = TT_ASSETS_APP_ICON_DISPLAY_SETTINGS,
.appIcon = LVGL_SYMBOL_DISPLAY_SETTINGS,
.appCategory = Category::Settings,
.createApp = create<DisplayApp>
};
-1
View File
@@ -39,7 +39,6 @@ public:
extern const AppManifest manifest = {
.appId = "Files",
.appName = "Files",
.appIcon = TT_ASSETS_APP_ICON_FILES,
.appCategory = Category::System,
.appFlags = AppManifest::Flags::Hidden,
.createApp = create<FilesApp>
@@ -58,7 +58,6 @@ public:
extern const AppManifest manifest = {
.appId = "FileSelection",
.appName = "File Selection",
.appIcon = TT_ASSETS_APP_ICON_FILES,
.appCategory = Category::System,
.appFlags = AppManifest::Flags::Hidden,
.createApp = create<FileSelection>
@@ -10,6 +10,8 @@
#include <Tactility/service/gps/GpsState.h>
#include <Tactility/service/loader/Loader.h>
#include <tactility/lvgl_symbols_shared.h>
#include <cstring>
#include <format>
#include <lvgl.h>
@@ -453,7 +455,7 @@ public:
extern const AppManifest manifest = {
.appId = "GpsSettings",
.appName = "GPS",
.appIcon = LV_SYMBOL_GPS,
.appIcon = LVGL_SYMBOL_NAVIGATION,
.appCategory = Category::Settings,
.createApp = create<GpsSettingsApp>
};
@@ -11,11 +11,12 @@
#include <Tactility/Preferences.h>
#include <Tactility/RecursiveMutex.h>
#include <Tactility/service/loader/Loader.h>
#include <Tactility/Tactility.h>
#include <Tactility/Timer.h>
#include <format>
#include <tactility/lvgl_symbols_shared.h>
namespace tt::app::i2cscanner {
extern const AppManifest manifest;
@@ -410,7 +411,7 @@ void I2cScannerApp::onScanTimerFinished() {
extern const AppManifest manifest = {
.appId = "I2cScanner",
.appName = "I2C Scanner",
.appIcon = TT_ASSETS_APP_ICON_I2C_SETTINGS,
.appIcon = LVGL_SYMBOL_SEARCH,
.appCategory = Category::System,
.createApp = create<I2cScannerApp>
};
@@ -3,9 +3,10 @@
#include <Tactility/Tactility.h>
#include <Tactility/settings/KeyboardSettings.h>
#include <Tactility/Assets.h>
#include <Tactility/lvgl/Toolbar.h>
#include <tactility/lvgl_symbols_shared.h>
#include <lvgl.h>
// Forward declare driver functions
@@ -182,7 +183,7 @@ public:
extern const AppManifest manifest = {
.appId = "KeyboardSettings",
.appName = "Keyboard",
.appIcon = TT_ASSETS_APP_ICON_SETTINGS,
.appIcon = LVGL_SYMBOL_KEYBOARD_ALT,
.appCategory = Category::Settings,
.createApp = create<KeyboardSettingsApp>
};
+10 -12
View File
@@ -4,22 +4,24 @@
#include <Tactility/app/AppPaths.h>
#include <Tactility/app/AppRegistration.h>
#include <Tactility/hal/power/PowerDevice.h>
#include <Tactility/lvgl/Lvgl.h>
#include <Tactility/service/loader/Loader.h>
#include <Tactility/settings/BootSettings.h>
#include <cstring>
#include <lvgl.h>
#include <tactility/lvgl_fonts.h>
#include <tactility/lvgl_symbols_launcher.h>
namespace tt::app::launcher {
static const auto LOGGER = Logger("Launcher");
static int getButtonSize(hal::UiScale scale) {
if (scale == hal::UiScale::Smallest) {
return 40;
return 36; // icon size
} else {
return 64;
return 56;
}
}
@@ -41,7 +43,9 @@ class LauncherApp final : public App {
// create the image first
auto* button_image = lv_image_create(apps_button);
lv_obj_set_style_text_font(button_image, LVGL_SYMBOL_FONT_LAUNCHER, LV_STATE_DEFAULT);
lv_image_set_src(button_image, imageFile);
lv_obj_set_style_text_color(button_image, lv_theme_get_color_primary(button_image), LV_STATE_DEFAULT);
// Recolor handling:
// For color builds use theme primary color
@@ -119,7 +123,6 @@ public:
auto button_size = getButtonSize(ui_scale);
lv_obj_align(buttons_wrapper, LV_ALIGN_CENTER, 0, 0);
// lv_obj_set_style_pad_all(buttons_wrapper, 0, LV_STATE_DEFAULT);
lv_obj_set_size(buttons_wrapper, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
lv_obj_set_style_border_width(buttons_wrapper, 0, LV_STATE_DEFAULT);
lv_obj_set_flex_grow(buttons_wrapper, 1);
@@ -150,14 +153,9 @@ public:
margin = std::min<int32_t>(available_height / 16, button_size);
}
const auto paths = app.getPaths();
const auto apps_icon_path = lvgl::PATH_PREFIX + paths->getAssetsPath("icon_apps.png");
const auto files_icon_path = lvgl::PATH_PREFIX + paths->getAssetsPath("icon_files.png");
const auto settings_icon_path = lvgl::PATH_PREFIX + paths->getAssetsPath("icon_settings.png");
createAppButton(buttons_wrapper, ui_scale, apps_icon_path.c_str(), "AppList", margin, is_landscape_display);
createAppButton(buttons_wrapper, ui_scale, files_icon_path.c_str(), "Files", margin, is_landscape_display);
createAppButton(buttons_wrapper, ui_scale, settings_icon_path.c_str(), "Settings", margin, is_landscape_display);
createAppButton(buttons_wrapper, ui_scale, LVGL_SYMBOL_APPS, "AppList", margin, is_landscape_display);
createAppButton(buttons_wrapper, ui_scale, LVGL_SYMBOL_FOLDER, "Files", margin, is_landscape_display);
createAppButton(buttons_wrapper, ui_scale, LVGL_SYMBOL_SETTINGS, "Settings", margin, is_landscape_display);
if (shouldShowPowerButton()) {
auto* power_button = lv_btn_create(parent);
@@ -1,18 +1,16 @@
#include <Tactility/Assets.h>
#include <Tactility/RecursiveMutex.h>
#include <Tactility/app/timezone/TimeZone.h>
#include <Tactility/app/localesettings/TextResources.h>
#include <Tactility/lvgl/Toolbar.h>
#include <Tactility/lvgl/LvglSync.h>
#include <Tactility/service/loader/Loader.h>
#include <Tactility/settings/Time.h>
#include <Tactility/StringUtils.h>
#include <Tactility/settings/Language.h>
#include <Tactility/settings/SystemSettings.h>
#include <tactility/lvgl_symbols_shared.h>
#include <lvgl.h>
#include <map>
#include <sstream>
namespace tt::app::localesettings {
@@ -163,7 +161,7 @@ public:
extern const AppManifest manifest = {
.appId = "LocaleSettings",
.appName = "Region & Language",
.appIcon = TT_ASSETS_APP_ICON_TIME_DATE_SETTINGS,
.appIcon = LVGL_SYMBOL_LANGUAGE,
.appCategory = Category::Settings,
.createApp = create<LocaleSettingsApp>
};
+2 -2
View File
@@ -3,12 +3,12 @@
#include <Tactility/file/FileLock.h>
#include <Tactility/lvgl/Toolbar.h>
#include <Tactility/lvgl/LvglSync.h>
#include <Tactility/service/loader/Loader.h>
#include <Tactility/Assets.h>
#include <Tactility/file/File.h>
#include <lvgl.h>
#include <tactility/lvgl_symbols_shared.h>
namespace tt::app::notes {
@@ -209,7 +209,7 @@ class NotesApp final : public App {
extern const AppManifest manifest = {
.appId = "Notes",
.appName = "Notes",
.appIcon = TT_ASSETS_APP_ICON_NOTES,
.appIcon = LVGL_SYMBOL_EDIT_NOTE,
.createApp = create<NotesApp>
};
+3 -2
View File
@@ -6,8 +6,9 @@
#include <Tactility/hal/power/PowerDevice.h>
#include <Tactility/Timer.h>
#include <Tactility/Assets.h>
#include <tactility/hal/Device.h>
#include <tactility/lvgl_symbols_shared.h>
#include <lvgl.h>
@@ -191,7 +192,7 @@ public:
extern const AppManifest manifest = {
.appId = "Power",
.appName = "Power",
.appIcon = TT_ASSETS_APP_ICON_POWER_SETTINGS,
.appIcon = LVGL_SYMBOL_ELECTRIC_BOLT,
.appCategory = Category::Settings,
.createApp = create<PowerApp>
};
@@ -15,6 +15,8 @@
#include <Tactility/lvgl/Toolbar.h>
#include <Tactility/service/screenshot/Screenshot.h>
#include <tactility/lvgl_symbols_shared.h>
namespace tt::app::screenshot {
static const auto LOGGER = Logger("Screenshot");
@@ -283,7 +285,7 @@ void ScreenshotApp::onShow(AppContext& appContext, lv_obj_t* parent) {
extern const AppManifest manifest = {
.appId = "Screenshot",
.appName = "Screenshot",
.appIcon = LV_SYMBOL_IMAGE,
.appIcon = LVGL_SYMBOL_IMAGE,
.appCategory = Category::System,
.createApp = create<ScreenshotApp>
};
+8 -4
View File
@@ -2,8 +2,10 @@
#include <Tactility/lvgl/Toolbar.h>
#include <Tactility/service/loader/Loader.h>
#include <Tactility/Assets.h>
#include <tactility/check.h>
#include <tactility/lvgl_symbols_shared.h>
#include <tactility/lvgl_fonts.h>
#include <lvgl.h>
#include <algorithm>
@@ -17,9 +19,11 @@ static void onAppPressed(lv_event_t* e) {
static void createWidget(const std::shared_ptr<AppManifest>& manifest, void* parent) {
check(parent);
auto* list = (lv_obj_t*)parent;
const void* icon = !manifest->appIcon.empty() ? manifest->appIcon.c_str() : TT_ASSETS_APP_ICON_FALLBACK;
auto* list = static_cast<lv_obj_t*>(parent);
const void* icon = !manifest->appIcon.empty() ? manifest->appIcon.c_str() : LVGL_SYMBOL_TOOLBAR;
auto* btn = lv_list_add_button(list, icon, manifest->appName.c_str());
lv_obj_t* image = lv_obj_get_child(btn, 0);
lv_obj_set_style_text_font(image, LVGL_SYMBOL_FONT_DEFAULT, LV_PART_MAIN);
lv_obj_add_event_cb(btn, &onAppPressed, LV_EVENT_SHORT_CLICKED, (void*)manifest.get());
}
@@ -48,7 +52,7 @@ class SettingsApp final : public App {
extern const AppManifest manifest = {
.appId = "Settings",
.appName = "Settings",
.appIcon = TT_ASSETS_APP_ICON_SETTINGS,
.appIcon = LVGL_SYMBOL_SETTINGS,
.appCategory = Category::System,
.appFlags = AppManifest::Flags::Hidden,
.createApp = create<SettingsApp>
@@ -10,6 +10,7 @@
#include <algorithm>
#include <format>
#include <lvgl.h>
#include <tactility/lvgl_symbols_shared.h>
#include <utility>
#include <cstring>
@@ -701,7 +702,7 @@ class SystemInfoApp final : public App {
extern const AppManifest manifest = {
.appId = "SystemInfo",
.appName = "System Info",
.appIcon = TT_ASSETS_APP_ICON_SYSTEM_INFO,
.appIcon = LVGL_SYMBOL_AREA_CHART,
.appCategory = Category::System,
.createApp = create<SystemInfoApp>
};
@@ -1,4 +1,3 @@
#include <Tactility/Assets.h>
#include <Tactility/app/AppManifest.h>
#include <Tactility/app/timezone/TimeZone.h>
#include <Tactility/Logger.h>
@@ -11,6 +10,8 @@
#include <lvgl.h>
#include <tactility/lvgl_symbols_shared.h>
namespace tt::app::timedatesettings {
static const auto LOGGER = Logger("TimeDate");
@@ -154,7 +155,7 @@ public:
extern const AppManifest manifest = {
.appId = "TimeDateSettings",
.appName = "Time & Date",
.appIcon = TT_ASSETS_APP_ICON_TIME_DATE_SETTINGS,
.appIcon = LVGL_SYMBOL_CALENDAR_MONTH,
.appCategory = Category::Settings,
.createApp = create<TimeDateSettingsApp>
};
@@ -3,11 +3,12 @@
#include <Tactility/Tactility.h>
#include <Tactility/settings/TrackballSettings.h>
#include <Tactility/Assets.h>
#include <Tactility/lvgl/Toolbar.h>
#include <lvgl.h>
#include <tactility/lvgl_symbols_shared.h>
// Forward declare driver functions
namespace trackball {
void setEnabled(bool enabled);
@@ -209,7 +210,7 @@ public:
extern const AppManifest manifest = {
.appId = "TrackballSettings",
.appName = "Trackball",
.appIcon = TT_ASSETS_APP_ICON_SETTINGS,
.appIcon = LVGL_SYMBOL_CIRCLE,
.appCategory = Category::Settings,
.createApp = create<TrackballSettingsApp>
};
@@ -1,12 +1,12 @@
#include "Tactility/app/App.h"
#include "Tactility/app/AppManifest.h"
#include "Tactility/lvgl/Toolbar.h"
#include <Tactility/CoreDefines.h>
#include <Tactility/app/App.h>
#include <Tactility/app/AppManifest.h>
#include <Tactility/hal/usb/Usb.h>
#include <Tactility/lvgl/Toolbar.h>
#include <lvgl.h>
#include <tactility/lvgl_symbols_shared.h>
#define TAG "usb_settings"
namespace tt::app::usbsettings {
@@ -62,7 +62,7 @@ class UsbSettingsApp : public App {
extern const AppManifest manifest = {
.appId = "UsbSettings",
.appName = "USB",
.appIcon = LV_SYMBOL_USB,
.appIcon = LVGL_SYMBOL_USB,
.appCategory = Category::Settings,
.createApp = create<UsbSettingsApp>
};
@@ -12,6 +12,7 @@
#include <Tactility/Logger.h>
#include <lvgl.h>
#include <tactility/lvgl_symbols_shared.h>
#include <esp_netif.h>
#include <esp_wifi.h>
@@ -417,7 +418,7 @@ public:
extern const AppManifest manifest = {
.appId = "WebServerSettings",
.appName = "Web Server",
.appIcon = TT_ASSETS_APP_ICON_SETTINGS,
.appIcon = LVGL_SYMBOL_CLOUD,
.appCategory = Category::System,
.createApp = create<WebServerSettingsApp>
};
@@ -9,6 +9,8 @@
#include <Tactility/lvgl/LvglSync.h>
#include <Tactility/service/loader/Loader.h>
#include <tactility/lvgl_symbols_shared.h>
namespace tt::app::wifimanage {
static const auto LOGGER = Logger("WifiManage");
@@ -142,7 +144,7 @@ void WifiManage::onHide(AppContext& app) {
extern const AppManifest manifest = {
.appId = "WifiManage",
.appName = "Wi-Fi",
.appIcon = LV_SYMBOL_WIFI,
.appIcon = LVGL_SYMBOL_WIFI,
.appCategory = Category::Settings,
.createApp = create<WifiManage>
};