153 lines
3.9 KiB
C
153 lines
3.9 KiB
C
#include "os_app.h"
|
|
#include "os_gfx.h"
|
|
#include "os_status.h"
|
|
#include "os_event.h"
|
|
#include <string.h>
|
|
#include "esp_log.h"
|
|
|
|
static const char *TAG = "SYS_APP";
|
|
|
|
#define MAX_APPS 16
|
|
static const sys_app_t *s_registry[MAX_APPS];
|
|
static size_t s_app_count = 0;
|
|
|
|
static const sys_app_t *s_current_app = NULL;
|
|
static bool s_in_launcher = true;
|
|
static size_t s_launcher_selected = 0;
|
|
|
|
static void launcher_update(uint32_t delta_ms)
|
|
{
|
|
sys_status_t status;
|
|
sys_status_get(&status);
|
|
sys_gfx_draw_status_bar(&status);
|
|
|
|
const char *names[MAX_APPS];
|
|
for (size_t i = 0; i < s_app_count; i++) {
|
|
names[i] = s_registry[i]->name;
|
|
}
|
|
sys_gfx_draw_menu(10, names, s_app_count, s_launcher_selected);
|
|
}
|
|
|
|
static void launcher_handle_input(input_action_t action)
|
|
{
|
|
if (s_app_count == 0) return;
|
|
|
|
if (action == INPUT_ACTION_CLICK) {
|
|
s_launcher_selected = (s_launcher_selected + 1) % s_app_count;
|
|
} else if (action == INPUT_ACTION_DOUBLE_CLICK) {
|
|
/* Tap 1 already stepped +1; stepping -2 results in a net -1 (previous entry) */
|
|
s_launcher_selected = (s_launcher_selected + s_app_count - 2) % s_app_count;
|
|
} else if (action == INPUT_ACTION_LONG_PRESS) {
|
|
sys_app_launch_by_index(s_launcher_selected);
|
|
}
|
|
}
|
|
|
|
esp_err_t sys_app_init(void)
|
|
{
|
|
s_app_count = 0;
|
|
s_current_app = NULL;
|
|
s_in_launcher = true;
|
|
s_launcher_selected = 0;
|
|
sys_status_set_active_app_name("Launcher");
|
|
ESP_LOGI(TAG, "App Manager initialized");
|
|
return ESP_OK;
|
|
}
|
|
|
|
esp_err_t sys_app_register(const sys_app_t *app)
|
|
{
|
|
if (!app || !app->id || !app->name) return ESP_ERR_INVALID_ARG;
|
|
if (s_app_count >= MAX_APPS) return ESP_ERR_NO_MEM;
|
|
|
|
s_registry[s_app_count++] = app;
|
|
if (app->init) {
|
|
app->init();
|
|
}
|
|
ESP_LOGI(TAG, "Registered app: [%s] '%s'", app->id, app->name);
|
|
return ESP_OK;
|
|
}
|
|
|
|
esp_err_t sys_app_launch_by_id(const char *id)
|
|
{
|
|
if (!id) return ESP_ERR_INVALID_ARG;
|
|
for (size_t i = 0; i < s_app_count; i++) {
|
|
if (strcmp(s_registry[i]->id, id) == 0) {
|
|
return sys_app_launch_by_index(i);
|
|
}
|
|
}
|
|
ESP_LOGW(TAG, "App not found: %s", id);
|
|
return ESP_ERR_NOT_FOUND;
|
|
}
|
|
|
|
esp_err_t sys_app_launch_by_index(size_t index)
|
|
{
|
|
if (index >= s_app_count) return ESP_ERR_INVALID_ARG;
|
|
|
|
if (s_current_app && s_current_app->exit) {
|
|
s_current_app->exit();
|
|
}
|
|
|
|
s_current_app = s_registry[index];
|
|
s_in_launcher = false;
|
|
sys_status_set_active_app_name(s_current_app->name);
|
|
|
|
if (s_current_app->enter) {
|
|
s_current_app->enter();
|
|
}
|
|
|
|
sys_event_post(SYS_EVENT_APP_SWITCH, (int32_t)index, (void *)s_current_app->id);
|
|
sys_gfx_show_toast(s_current_app->name, 800);
|
|
ESP_LOGI(TAG, "Switched to app: %s", s_current_app->name);
|
|
return ESP_OK;
|
|
}
|
|
|
|
void sys_app_launch_launcher(void)
|
|
{
|
|
if (s_current_app && s_current_app->exit) {
|
|
s_current_app->exit();
|
|
}
|
|
s_current_app = NULL;
|
|
s_in_launcher = true;
|
|
sys_status_set_active_app_name("Launcher");
|
|
sys_gfx_show_toast("Launcher", 600);
|
|
ESP_LOGI(TAG, "Returned to App Launcher");
|
|
}
|
|
|
|
const sys_app_t *sys_app_get_current(void)
|
|
{
|
|
return s_current_app;
|
|
}
|
|
|
|
void sys_app_update(uint32_t delta_ms)
|
|
{
|
|
if (s_in_launcher) {
|
|
launcher_update(delta_ms);
|
|
} else if (s_current_app && s_current_app->update) {
|
|
s_current_app->update(delta_ms);
|
|
}
|
|
}
|
|
|
|
void sys_app_dispatch_input(input_action_t action)
|
|
{
|
|
if (action == INPUT_ACTION_HOLD_HOME || action == INPUT_ACTION_TRIPLE_CLICK) {
|
|
sys_app_launch_launcher();
|
|
return;
|
|
}
|
|
|
|
if (s_in_launcher) {
|
|
launcher_handle_input(action);
|
|
} else if (s_current_app && s_current_app->handle_input) {
|
|
s_current_app->handle_input(action);
|
|
}
|
|
}
|
|
|
|
size_t sys_app_get_count(void)
|
|
{
|
|
return s_app_count;
|
|
}
|
|
|
|
const sys_app_t *sys_app_get_by_index(size_t index)
|
|
{
|
|
if (index >= s_app_count) return NULL;
|
|
return s_registry[index];
|
|
}
|