Sort apps on Desktop and Settings (#87)
- Sort apps by name - Make manifest IDs consistent - Updated screenshots - Renamed Screenshot app so it always renders at the bottom of the app list
This commit is contained in:
parent
caa8756998
commit
76c14a5f47
@ -21,20 +21,17 @@
|
|||||||
- Refactor hardware configuration init methods to return esp_err_t instead of bool
|
- Refactor hardware configuration init methods to return esp_err_t instead of bool
|
||||||
|
|
||||||
# Core Ideas
|
# Core Ideas
|
||||||
- Make a HAL? It would mainly be there to support PC development. It's a lot of effort for supporting what's effectively a dev-only feature.
|
|
||||||
- Support for displays with different DPI. Consider the layer-based system like on Android.
|
- Support for displays with different DPI. Consider the layer-based system like on Android.
|
||||||
- If present, use LED to show boot status
|
- If present, use LED to show boot status
|
||||||
- 2 wire speaker support
|
- 2 wire speaker support
|
||||||
- tt_app_start() and similar functions as proxies for Loader app start/stop/etc.
|
- tt::startApp() and similar functions as proxies for Loader app start/stop/etc.
|
||||||
- tt_app_set_result() for apps that need to return data to other apps (e.g. file selection)
|
- tt::setAppResult() for apps that need to return data to other apps (e.g. file selection)
|
||||||
- Wi-Fi using dispatcher to dispatch its main functionality to the dedicated Wi-Fi CPU core (to avoid main loop hack)
|
- Wi-Fi using dispatcher to dispatch its main functionality to the dedicated Wi-Fi CPU core (to avoid main loop hack)
|
||||||
|
|
||||||
# App Improvement Ideas
|
# App Improvement Ideas
|
||||||
- Sort desktop apps by name.
|
|
||||||
- Light/dark mode selection in Display settings app.
|
- Light/dark mode selection in Display settings app.
|
||||||
|
|
||||||
# App Ideas
|
# App Ideas
|
||||||
- File viewer (images, text... binary?)
|
|
||||||
- BlueTooth keyboard app
|
- BlueTooth keyboard app
|
||||||
- Chip 8 emulator
|
- Chip 8 emulator
|
||||||
- BadUSB
|
- BadUSB
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 3.9 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.8 KiB |
@ -70,4 +70,8 @@ typedef struct AppManifest {
|
|||||||
const AppOnHide _Nullable on_hide = nullptr;
|
const AppOnHide _Nullable on_hide = nullptr;
|
||||||
} AppManifest;
|
} AppManifest;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
bool operator()(const AppManifest* a, const AppManifest* b) const { return a->name < b->name; }
|
||||||
|
} SortAppManifestByName;
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@ -42,22 +42,14 @@ _Nullable const AppManifest * app_manifest_registry_find_by_id(const std::string
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void app_manifest_registry_for_each_of_type(AppType type, void* _Nullable context, AppManifestCallback callback) {
|
std::vector<const AppManifest*> app_manifest_registry_get() {
|
||||||
|
std::vector<const AppManifest*> manifests;
|
||||||
app_registry_lock();
|
app_registry_lock();
|
||||||
for (auto& it : app_manifest_map) {
|
for (const auto& item: app_manifest_map) {
|
||||||
if (it.second->type == type) {
|
manifests.push_back(item.second);
|
||||||
callback(it.second, context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
app_registry_unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
void app_manifest_registry_for_each(AppManifestCallback callback, void* _Nullable context) {
|
|
||||||
app_registry_lock();
|
|
||||||
for (auto& it : app_manifest_map) {
|
|
||||||
callback(it.second, context);
|
|
||||||
}
|
}
|
||||||
app_registry_unlock();
|
app_registry_unlock();
|
||||||
|
return manifests;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@ -2,16 +2,14 @@
|
|||||||
|
|
||||||
#include "AppManifest.h"
|
#include "AppManifest.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace tt {
|
namespace tt {
|
||||||
|
|
||||||
typedef void (*AppManifestCallback)(const AppManifest*, void* context);
|
|
||||||
|
|
||||||
void app_manifest_registry_init();
|
void app_manifest_registry_init();
|
||||||
void app_manifest_registry_add(const AppManifest* manifest);
|
void app_manifest_registry_add(const AppManifest* manifest);
|
||||||
void app_manifest_registry_remove(const AppManifest* manifest);
|
void app_manifest_registry_remove(const AppManifest* manifest);
|
||||||
const AppManifest _Nullable* app_manifest_registry_find_by_id(const std::string& id);
|
const AppManifest _Nullable* app_manifest_registry_find_by_id(const std::string& id);
|
||||||
void app_manifest_registry_for_each(AppManifestCallback callback, void* _Nullable context);
|
std::vector<const AppManifest*> app_manifest_registry_get();
|
||||||
void app_manifest_registry_for_each_of_type(AppType type, void* _Nullable context, AppManifestCallback callback);
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
#include "Assets.h"
|
#include "Assets.h"
|
||||||
#include "Check.h"
|
#include "Check.h"
|
||||||
#include "lvgl.h"
|
#include "lvgl.h"
|
||||||
|
#include <algorithm>
|
||||||
#include "Services/Loader/Loader.h"
|
#include "Services/Loader/Loader.h"
|
||||||
|
|
||||||
namespace tt::app::desktop {
|
namespace tt::app::desktop {
|
||||||
@ -27,14 +28,26 @@ static void desktop_show(TT_UNUSED App app, lv_obj_t* parent) {
|
|||||||
lv_obj_set_size(list, LV_PCT(100), LV_PCT(100));
|
lv_obj_set_size(list, LV_PCT(100), LV_PCT(100));
|
||||||
lv_obj_center(list);
|
lv_obj_center(list);
|
||||||
|
|
||||||
|
auto manifests = app_manifest_registry_get();
|
||||||
|
std::sort(manifests.begin(), manifests.end(), SortAppManifestByName);
|
||||||
|
|
||||||
lv_list_add_text(list, "User");
|
lv_list_add_text(list, "User");
|
||||||
app_manifest_registry_for_each_of_type(AppTypeUser, list, create_app_widget);
|
for (const auto& manifest: manifests) {
|
||||||
|
if (manifest->type == AppTypeUser) {
|
||||||
|
create_app_widget(manifest, list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lv_list_add_text(list, "System");
|
lv_list_add_text(list, "System");
|
||||||
app_manifest_registry_for_each_of_type(AppTypeSystem, list, create_app_widget);
|
for (const auto& manifest: manifests) {
|
||||||
|
if (manifest->type == AppTypeSystem) {
|
||||||
|
create_app_widget(manifest, list);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern const AppManifest manifest = {
|
extern const AppManifest manifest = {
|
||||||
.id = "desktop",
|
.id = "Desktop",
|
||||||
.name = "Desktop",
|
.name = "Desktop",
|
||||||
.type = AppTypeDesktop,
|
.type = AppTypeDesktop,
|
||||||
.on_show = &desktop_show,
|
.on_show = &desktop_show,
|
||||||
|
|||||||
@ -121,7 +121,7 @@ static void app_hide(TT_UNUSED App app) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern const AppManifest manifest = {
|
extern const AppManifest manifest = {
|
||||||
.id = "display",
|
.id = "Display",
|
||||||
.name = "Display",
|
.name = "Display",
|
||||||
.icon = TT_ASSETS_APP_ICON_DISPLAY_SETTINGS,
|
.icon = TT_ASSETS_APP_ICON_DISPLAY_SETTINGS,
|
||||||
.type = AppTypeSettings,
|
.type = AppTypeSettings,
|
||||||
|
|||||||
@ -222,7 +222,7 @@ static void on_stop(App app) {
|
|||||||
// endregion Lifecycle
|
// endregion Lifecycle
|
||||||
|
|
||||||
extern const AppManifest manifest = {
|
extern const AppManifest manifest = {
|
||||||
.id = "files",
|
.id = "Files",
|
||||||
.name = "Files",
|
.name = "Files",
|
||||||
.icon = TT_ASSETS_APP_ICON_FILES,
|
.icon = TT_ASSETS_APP_ICON_FILES,
|
||||||
.type = AppTypeSystem,
|
.type = AppTypeSystem,
|
||||||
|
|||||||
@ -201,7 +201,7 @@ static void on_stop(App app) {
|
|||||||
// endregion App lifecycle
|
// endregion App lifecycle
|
||||||
|
|
||||||
extern const AppManifest manifest = {
|
extern const AppManifest manifest = {
|
||||||
.id = "gpio",
|
.id = "Gpio",
|
||||||
.name = "GPIO",
|
.name = "GPIO",
|
||||||
.type = AppTypeSystem,
|
.type = AppTypeSystem,
|
||||||
.on_start = &on_start,
|
.on_start = &on_start,
|
||||||
|
|||||||
@ -110,7 +110,7 @@ static void app_stop(App app) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern const AppManifest manifest = {
|
extern const AppManifest manifest = {
|
||||||
.id = "power",
|
.id = "Power",
|
||||||
.name = "Power",
|
.name = "Power",
|
||||||
.icon = TT_ASSETS_APP_ICON_POWER_SETTINGS,
|
.icon = TT_ASSETS_APP_ICON_POWER_SETTINGS,
|
||||||
.type = AppTypeSettings,
|
.type = AppTypeSettings,
|
||||||
|
|||||||
@ -18,8 +18,8 @@ static void on_stop(App app) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern const AppManifest manifest = {
|
extern const AppManifest manifest = {
|
||||||
.id = "screenshot",
|
.id = "Screenshot",
|
||||||
.name = "Screenshot",
|
.name = "_Screenshot", // So it gets put at the bottom of the desktop and becomes less visible on small screen devices
|
||||||
.icon = LV_SYMBOL_IMAGE,
|
.icon = LV_SYMBOL_IMAGE,
|
||||||
.type = AppTypeSystem,
|
.type = AppTypeSystem,
|
||||||
.on_start = &on_start,
|
.on_start = &on_start,
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
#include "AppManifestRegistry.h"
|
#include "AppManifestRegistry.h"
|
||||||
#include "Assets.h"
|
#include "Assets.h"
|
||||||
#include "Check.h"
|
#include "Check.h"
|
||||||
#include "lvgl.h"
|
|
||||||
#include "Services/Loader/Loader.h"
|
#include "Services/Loader/Loader.h"
|
||||||
#include "Ui/Toolbar.h"
|
#include "Ui/Toolbar.h"
|
||||||
|
#include "lvgl.h"
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
namespace tt::app::settings {
|
namespace tt::app::settings {
|
||||||
|
|
||||||
@ -32,11 +33,17 @@ static void on_show(App app, lv_obj_t* 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);
|
||||||
|
|
||||||
app_manifest_registry_for_each_of_type(AppTypeSettings, list, create_app_widget);
|
auto manifests = app_manifest_registry_get();
|
||||||
|
std::sort(manifests.begin(), manifests.end(), SortAppManifestByName);
|
||||||
|
for (const auto& manifest: manifests) {
|
||||||
|
if (manifest->type == AppTypeSettings) {
|
||||||
|
create_app_widget(manifest, list);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern const AppManifest manifest = {
|
extern const AppManifest manifest = {
|
||||||
.id = "settings",
|
.id = "Settings",
|
||||||
.name = "Settings",
|
.name = "Settings",
|
||||||
.icon = TT_ASSETS_APP_ICON_SETTINGS,
|
.icon = TT_ASSETS_APP_ICON_SETTINGS,
|
||||||
.type = AppTypeSystem,
|
.type = AppTypeSystem,
|
||||||
|
|||||||
@ -102,7 +102,7 @@ static void on_show(App app, lv_obj_t* parent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern const AppManifest manifest = {
|
extern const AppManifest manifest = {
|
||||||
.id = "systeminfo",
|
.id = "SystemInfo",
|
||||||
.name = "System Info",
|
.name = "System Info",
|
||||||
.icon = TT_ASSETS_APP_ICON_SYSTEM_INFO,
|
.icon = TT_ASSETS_APP_ICON_SYSTEM_INFO,
|
||||||
.type = AppTypeSystem,
|
.type = AppTypeSystem,
|
||||||
|
|||||||
@ -133,7 +133,7 @@ static void app_stop(App app) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern const AppManifest manifest = {
|
extern const AppManifest manifest = {
|
||||||
.id = "wifi_connect",
|
.id = "WifiConnect",
|
||||||
.name = "Wi-Fi Connect",
|
.name = "Wi-Fi Connect",
|
||||||
.icon = LV_SYMBOL_WIFI,
|
.icon = LV_SYMBOL_WIFI,
|
||||||
.type = AppTypeSettings,
|
.type = AppTypeSettings,
|
||||||
|
|||||||
@ -26,7 +26,7 @@ static void on_connect(const char* ssid) {
|
|||||||
Bundle bundle;
|
Bundle bundle;
|
||||||
bundle.putString(WIFI_CONNECT_PARAM_SSID, ssid);
|
bundle.putString(WIFI_CONNECT_PARAM_SSID, ssid);
|
||||||
bundle.putString(WIFI_CONNECT_PARAM_PASSWORD, "");
|
bundle.putString(WIFI_CONNECT_PARAM_PASSWORD, "");
|
||||||
service::loader::start_app("wifi_connect", false, bundle);
|
service::loader::start_app("WifiConnect", false, bundle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -21,7 +21,7 @@ namespace service {
|
|||||||
namespace statusbar { extern const ServiceManifest manifest; }
|
namespace statusbar { extern const ServiceManifest manifest; }
|
||||||
}
|
}
|
||||||
|
|
||||||
static const ServiceManifest* const system_services[] = {
|
static const std::vector<const ServiceManifest*> system_services = {
|
||||||
&service::loader::manifest,
|
&service::loader::manifest,
|
||||||
&service::gui::manifest, // depends on loader service
|
&service::gui::manifest, // depends on loader service
|
||||||
#ifndef ESP_PLATFORM // Screenshots don't work yet on ESP32
|
#ifndef ESP_PLATFORM // Screenshots don't work yet on ESP32
|
||||||
@ -54,7 +54,7 @@ namespace app {
|
|||||||
extern const AppManifest screenshot_app;
|
extern const AppManifest screenshot_app;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const AppManifest* const system_apps[] = {
|
static const std::vector<const AppManifest*> system_apps = {
|
||||||
&app::desktop::manifest,
|
&app::desktop::manifest,
|
||||||
&app::files::manifest,
|
&app::files::manifest,
|
||||||
&app::gpio::manifest,
|
&app::gpio::manifest,
|
||||||
@ -75,10 +75,8 @@ static const AppManifest* const system_apps[] = {
|
|||||||
|
|
||||||
static void register_system_apps() {
|
static void register_system_apps() {
|
||||||
TT_LOG_I(TAG, "Registering default apps");
|
TT_LOG_I(TAG, "Registering default apps");
|
||||||
|
for (const auto& app_manifest: system_apps) {
|
||||||
int app_count = sizeof(system_apps) / sizeof(AppManifest*);
|
app_manifest_registry_add(app_manifest);
|
||||||
for (int i = 0; i < app_count; ++i) {
|
|
||||||
app_manifest_registry_add(system_apps[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getConfiguration()->hardware->power != nullptr) {
|
if (getConfiguration()->hardware->power != nullptr) {
|
||||||
@ -101,10 +99,9 @@ static void register_user_apps(const AppManifest* const apps[TT_CONFIG_APPS_LIMI
|
|||||||
|
|
||||||
static void register_and_start_system_services() {
|
static void register_and_start_system_services() {
|
||||||
TT_LOG_I(TAG, "Registering and starting system services");
|
TT_LOG_I(TAG, "Registering and starting system services");
|
||||||
int app_count = sizeof(system_services) / sizeof(ServiceManifest*);
|
for (const auto& service_manifest: system_services) {
|
||||||
for (int i = 0; i < app_count; ++i) {
|
service_registry_add(service_manifest);
|
||||||
service_registry_add(system_services[i]);
|
tt_check(service_registry_start(service_manifest->id));
|
||||||
tt_check(service_registry_start(system_services[i]->id));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,7 +122,6 @@ static void register_and_start_user_services(const ServiceManifest* const servic
|
|||||||
void init(const Configuration* config) {
|
void init(const Configuration* config) {
|
||||||
TT_LOG_I(TAG, "init started");
|
TT_LOG_I(TAG, "init started");
|
||||||
|
|
||||||
|
|
||||||
// Assign early so starting services can use it
|
// Assign early so starting services can use it
|
||||||
config_instance = config;
|
config_instance = config;
|
||||||
|
|
||||||
|
|||||||
@ -745,7 +745,7 @@ static void service_stop(Service& service) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern const ServiceManifest manifest = {
|
extern const ServiceManifest manifest = {
|
||||||
.id = "wifi",
|
.id = "Wifi",
|
||||||
.on_start = &service_start,
|
.on_start = &service_start,
|
||||||
.on_stop = &service_stop
|
.on_stop = &service_stop
|
||||||
};
|
};
|
||||||
|
|||||||
@ -177,7 +177,7 @@ static void service_stop(TT_UNUSED Service& service) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern const ServiceManifest manifest = {
|
extern const ServiceManifest manifest = {
|
||||||
.id = "wifi",
|
.id = "Wifi",
|
||||||
.on_start = &service_start,
|
.on_start = &service_start,
|
||||||
.on_stop = &service_stop
|
.on_stop = &service_stop
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user