mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-04-24 03:29:57 -07:00
Loader pick all menu apps from file
This commit is contained in:
@@ -24,7 +24,7 @@ static void xtreme_app_scene_interface_mainmenu_app_changed(VariableItem* item)
|
||||
XtremeApp* app = variable_item_get_context(item);
|
||||
app->mainmenu_app_index = variable_item_get_current_value_index(item);
|
||||
variable_item_set_current_value_text(
|
||||
item, *CharList_get(app->mainmenu_app_names, app->mainmenu_app_index));
|
||||
item, *CharList_get(app->mainmenu_app_labels, app->mainmenu_app_index));
|
||||
}
|
||||
|
||||
void xtreme_app_scene_interface_mainmenu_on_enter(void* context) {
|
||||
@@ -42,14 +42,14 @@ void xtreme_app_scene_interface_mainmenu_on_enter(void* context) {
|
||||
item = variable_item_list_add(
|
||||
var_item_list,
|
||||
"App",
|
||||
CharList_size(app->mainmenu_app_names),
|
||||
CharList_size(app->mainmenu_app_labels),
|
||||
xtreme_app_scene_interface_mainmenu_app_changed,
|
||||
app);
|
||||
app->mainmenu_app_index = 0;
|
||||
variable_item_set_current_value_index(item, app->mainmenu_app_index);
|
||||
if(CharList_size(app->mainmenu_app_names)) {
|
||||
if(CharList_size(app->mainmenu_app_labels)) {
|
||||
variable_item_set_current_value_text(
|
||||
item, *CharList_get(app->mainmenu_app_names, app->mainmenu_app_index));
|
||||
item, *CharList_get(app->mainmenu_app_labels, app->mainmenu_app_index));
|
||||
} else {
|
||||
variable_item_set_current_value_text(item, "None");
|
||||
}
|
||||
@@ -78,12 +78,12 @@ bool xtreme_app_scene_interface_mainmenu_on_event(void* context, SceneManagerEve
|
||||
consumed = true;
|
||||
switch(event.event) {
|
||||
case VarItemListIndexRemoveApp:
|
||||
if(!CharList_size(app->mainmenu_app_names)) break;
|
||||
if(!CharList_size(app->mainmenu_app_paths)) break;
|
||||
if(!CharList_size(app->mainmenu_app_labels)) break;
|
||||
if(!CharList_size(app->mainmenu_app_exes)) break;
|
||||
CharList_remove_v(
|
||||
app->mainmenu_app_names, app->mainmenu_app_index, app->mainmenu_app_index + 1);
|
||||
app->mainmenu_app_labels, app->mainmenu_app_index, app->mainmenu_app_index + 1);
|
||||
CharList_remove_v(
|
||||
app->mainmenu_app_paths, app->mainmenu_app_index, app->mainmenu_app_index + 1);
|
||||
app->mainmenu_app_exes, app->mainmenu_app_index, app->mainmenu_app_index + 1);
|
||||
app->save_mainmenu_apps = true;
|
||||
app->require_reboot = true;
|
||||
scene_manager_previous_scene(app->scene_manager);
|
||||
|
||||
@@ -30,11 +30,11 @@ void xtreme_app_scene_interface_mainmenu_add_on_enter(void* context) {
|
||||
};
|
||||
|
||||
if(dialog_file_browser_show(app->dialogs, string, string, &browser_options)) {
|
||||
CharList_push_back(app->mainmenu_app_paths, strdup(furi_string_get_cstr(string)));
|
||||
CharList_push_back(app->mainmenu_app_exes, strdup(furi_string_get_cstr(string)));
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
flipper_application_load_name_and_icon(string, storage, NULL, string);
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
CharList_push_back(app->mainmenu_app_names, strdup(furi_string_get_cstr(string)));
|
||||
CharList_push_back(app->mainmenu_app_labels, strdup(furi_string_get_cstr(string)));
|
||||
app->save_mainmenu_apps = true;
|
||||
app->require_reboot = true;
|
||||
}
|
||||
|
||||
@@ -16,11 +16,12 @@ bool xtreme_app_apply(XtremeApp* app) {
|
||||
|
||||
if(app->save_mainmenu_apps) {
|
||||
Stream* stream = file_stream_alloc(storage);
|
||||
if(file_stream_open(stream, XTREME_APPS_PATH, FSAM_READ_WRITE, FSOM_CREATE_ALWAYS)) {
|
||||
if(file_stream_open(stream, XTREME_MENU_PATH, FSAM_READ_WRITE, FSOM_CREATE_ALWAYS)) {
|
||||
stream_write_format(stream, "MenuAppList Version %u\n", 0);
|
||||
CharList_it_t it;
|
||||
CharList_it(it, app->mainmenu_app_paths);
|
||||
for(size_t i = 0; i < CharList_size(app->mainmenu_app_paths); i++) {
|
||||
stream_write_format(stream, "%s\n", *CharList_get(app->mainmenu_app_paths, i));
|
||||
CharList_it(it, app->mainmenu_app_exes);
|
||||
for(size_t i = 0; i < CharList_size(app->mainmenu_app_exes); i++) {
|
||||
stream_write_format(stream, "%s\n", *CharList_get(app->mainmenu_app_exes, i));
|
||||
}
|
||||
}
|
||||
file_stream_close(stream);
|
||||
@@ -227,17 +228,18 @@ XtremeApp* xtreme_app_alloc() {
|
||||
free(name);
|
||||
storage_file_free(folder);
|
||||
|
||||
CharList_init(app->mainmenu_app_names);
|
||||
CharList_init(app->mainmenu_app_paths);
|
||||
CharList_init(app->mainmenu_app_labels);
|
||||
CharList_init(app->mainmenu_app_exes);
|
||||
Stream* stream = file_stream_alloc(storage);
|
||||
FuriString* line = furi_string_alloc();
|
||||
if(file_stream_open(stream, XTREME_APPS_PATH, FSAM_READ, FSOM_OPEN_EXISTING)) {
|
||||
if(file_stream_open(stream, XTREME_MENU_PATH, FSAM_READ, FSOM_OPEN_EXISTING)) {
|
||||
stream_read_line(stream, line);
|
||||
while(stream_read_line(stream, line)) {
|
||||
furi_string_replace_all(line, "\r", "");
|
||||
furi_string_replace_all(line, "\n", "");
|
||||
CharList_push_back(app->mainmenu_app_paths, strdup(furi_string_get_cstr(line)));
|
||||
CharList_push_back(app->mainmenu_app_exes, strdup(furi_string_get_cstr(line)));
|
||||
flipper_application_load_name_and_icon(line, storage, NULL, line);
|
||||
CharList_push_back(app->mainmenu_app_names, strdup(furi_string_get_cstr(line)));
|
||||
CharList_push_back(app->mainmenu_app_labels, strdup(furi_string_get_cstr(line)));
|
||||
}
|
||||
}
|
||||
furi_string_free(line);
|
||||
@@ -314,14 +316,14 @@ void xtreme_app_free(XtremeApp* app) {
|
||||
}
|
||||
CharList_clear(app->asset_pack_names);
|
||||
|
||||
for(CharList_it(it, app->mainmenu_app_names); !CharList_end_p(it); CharList_next(it)) {
|
||||
for(CharList_it(it, app->mainmenu_app_labels); !CharList_end_p(it); CharList_next(it)) {
|
||||
free(*CharList_cref(it));
|
||||
}
|
||||
CharList_clear(app->mainmenu_app_names);
|
||||
for(CharList_it(it, app->mainmenu_app_paths); !CharList_end_p(it); CharList_next(it)) {
|
||||
CharList_clear(app->mainmenu_app_labels);
|
||||
for(CharList_it(it, app->mainmenu_app_exes); !CharList_end_p(it); CharList_next(it)) {
|
||||
free(*CharList_cref(it));
|
||||
}
|
||||
CharList_clear(app->mainmenu_app_paths);
|
||||
CharList_clear(app->mainmenu_app_exes);
|
||||
|
||||
FrequencyList_clear(app->subghz_static_freqs);
|
||||
FrequencyList_clear(app->subghz_hopper_freqs);
|
||||
|
||||
@@ -42,8 +42,8 @@ typedef struct {
|
||||
|
||||
CharList_t asset_pack_names;
|
||||
uint8_t asset_pack_index;
|
||||
CharList_t mainmenu_app_names;
|
||||
CharList_t mainmenu_app_paths;
|
||||
CharList_t mainmenu_app_labels;
|
||||
CharList_t mainmenu_app_exes;
|
||||
uint8_t mainmenu_app_index;
|
||||
bool subghz_use_defaults;
|
||||
FrequencyList_t subghz_static_freqs;
|
||||
|
||||
@@ -134,9 +134,9 @@ FuriPubSub* loader_get_pubsub(Loader* loader) {
|
||||
return loader->pubsub;
|
||||
}
|
||||
|
||||
ExtMainAppList_t* loader_get_ext_main_apps(Loader* loader) {
|
||||
MenuAppList_t* loader_get_menu_apps(Loader* loader) {
|
||||
furi_assert(loader);
|
||||
return &loader->ext_main_apps;
|
||||
return &loader->menu_apps;
|
||||
}
|
||||
|
||||
// callbacks
|
||||
@@ -195,6 +195,31 @@ bool loader_menu_load_fap_meta(
|
||||
return true;
|
||||
}
|
||||
|
||||
static void loader_make_menu_file(Storage* storage) {
|
||||
Stream* new = file_stream_alloc(storage);
|
||||
if(!storage_file_exists(storage, XTREME_MENU_PATH)) {
|
||||
if(file_stream_open(new, XTREME_MENU_PATH, FSAM_WRITE, FSOM_CREATE_ALWAYS)) {
|
||||
stream_write_format(new, "MenuAppList Version %u\n", 0);
|
||||
for(size_t i = 0; i < FLIPPER_APPS_COUNT; i++) {
|
||||
stream_write_format(new, "%s\n", FLIPPER_APPS[i].name);
|
||||
}
|
||||
for(size_t i = 0; i < FLIPPER_EXTERNAL_APPS_COUNT - 1; i++) {
|
||||
stream_write_format(new, "%s\n", FLIPPER_EXTERNAL_APPS[i].name);
|
||||
}
|
||||
Stream* old = file_stream_alloc(storage);
|
||||
if(file_stream_open(old, XTREME_MENU_OLD_PATH, FSAM_READ, FSOM_OPEN_EXISTING)) {
|
||||
stream_copy(old, new, stream_size(old));
|
||||
}
|
||||
file_stream_close(old);
|
||||
stream_free(old);
|
||||
storage_common_remove(storage, XTREME_MENU_OLD_PATH);
|
||||
}
|
||||
file_stream_close(new);
|
||||
}
|
||||
file_stream_close(new);
|
||||
stream_free(new);
|
||||
}
|
||||
|
||||
static Loader* loader_alloc() {
|
||||
Loader* loader = malloc(sizeof(Loader));
|
||||
loader->pubsub = furi_pubsub_alloc();
|
||||
@@ -205,33 +230,76 @@ static Loader* loader_alloc() {
|
||||
loader->app.thread = NULL;
|
||||
loader->app.insomniac = false;
|
||||
loader->app.fap = NULL;
|
||||
ExtMainAppList_init(loader->ext_main_apps);
|
||||
MenuAppList_init(loader->menu_apps);
|
||||
|
||||
if(furi_hal_is_normal_boot()) {
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
FuriString* path = furi_string_alloc();
|
||||
FuriString* name = furi_string_alloc();
|
||||
Stream* stream = file_stream_alloc(storage);
|
||||
if(file_stream_open(stream, XTREME_APPS_PATH, FSAM_READ, FSOM_OPEN_EXISTING)) {
|
||||
while(stream_read_line(stream, path)) {
|
||||
furi_string_replace_all(path, "\r", "");
|
||||
furi_string_replace_all(path, "\n", "");
|
||||
const Icon* icon;
|
||||
if(!loader_menu_load_fap_meta(storage, path, name, &icon)) continue;
|
||||
ExtMainAppList_push_back(
|
||||
loader->ext_main_apps,
|
||||
(ExtMainApp){
|
||||
.name = strdup(furi_string_get_cstr(name)),
|
||||
.path = strdup(furi_string_get_cstr(path)),
|
||||
.icon = icon});
|
||||
if(!furi_hal_is_normal_boot()) return loader;
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
Stream* stream = file_stream_alloc(storage);
|
||||
FuriString* line = furi_string_alloc();
|
||||
FuriString* name = furi_string_alloc();
|
||||
do {
|
||||
|
||||
if(!file_stream_open(stream, XTREME_MENU_PATH, FSAM_READ_WRITE, FSOM_OPEN_EXISTING)) {
|
||||
file_stream_close(stream);
|
||||
loader_make_menu_file(storage);
|
||||
if(!file_stream_open(stream, XTREME_MENU_PATH, FSAM_READ_WRITE, FSOM_OPEN_EXISTING))
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t version;
|
||||
if(!stream_read_line(stream, line) ||
|
||||
sscanf(furi_string_get_cstr(line), "MenuAppList Version %lu", &version) != 1 ||
|
||||
version > 0) {
|
||||
file_stream_close(stream);
|
||||
storage_common_remove(storage, XTREME_MENU_PATH);
|
||||
loader_make_menu_file(storage);
|
||||
if(!file_stream_open(stream, XTREME_MENU_PATH, FSAM_READ_WRITE, FSOM_OPEN_EXISTING))
|
||||
break;
|
||||
if(!stream_read_line(stream, line) ||
|
||||
sscanf(furi_string_get_cstr(line), "MenuAppList Version %lu", &version) != 1 ||
|
||||
version > 0)
|
||||
break;
|
||||
}
|
||||
|
||||
while(stream_read_line(stream, line)) {
|
||||
furi_string_replace_all(line, "\r", "");
|
||||
furi_string_replace_all(line, "\n", "");
|
||||
const char* label = NULL;
|
||||
const Icon* icon = NULL;
|
||||
const char* exe = NULL;
|
||||
if(storage_file_exists(storage, furi_string_get_cstr(line))) {
|
||||
if(loader_menu_load_fap_meta(storage, line, name, &icon)) {
|
||||
label = strdup(furi_string_get_cstr(name));
|
||||
exe = strdup(furi_string_get_cstr(line));
|
||||
}
|
||||
} else {
|
||||
for(size_t i = 0; !exe && i < FLIPPER_APPS_COUNT; i++) {
|
||||
if(!strcmp(furi_string_get_cstr(line), FLIPPER_APPS[i].name)) {
|
||||
label = FLIPPER_APPS[i].name;
|
||||
icon = FLIPPER_APPS[i].icon;
|
||||
exe = FLIPPER_APPS[i].name;
|
||||
}
|
||||
}
|
||||
for(size_t i = 0; !exe && i < FLIPPER_EXTERNAL_APPS_COUNT; i++) {
|
||||
if(!strcmp(furi_string_get_cstr(line), FLIPPER_EXTERNAL_APPS[i].name)) {
|
||||
label = FLIPPER_EXTERNAL_APPS[i].name;
|
||||
icon = FLIPPER_EXTERNAL_APPS[i].icon;
|
||||
exe = FLIPPER_EXTERNAL_APPS[i].name;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(label && exe && icon) {
|
||||
MenuAppList_push_back(
|
||||
loader->menu_apps, (MenuApp){.label = label, .icon = icon, .exe = exe});
|
||||
}
|
||||
}
|
||||
file_stream_close(stream);
|
||||
stream_free(stream);
|
||||
furi_string_free(name);
|
||||
furi_string_free(path);
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
}
|
||||
|
||||
} while(false);
|
||||
furi_string_free(name);
|
||||
furi_string_free(line);
|
||||
file_stream_close(stream);
|
||||
stream_free(stream);
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
return loader;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <gui/icon.h>
|
||||
#include <m-list.h>
|
||||
|
||||
typedef struct {
|
||||
const char* name;
|
||||
const char* path;
|
||||
const Icon* icon;
|
||||
} ExtMainApp;
|
||||
|
||||
LIST_DEF(ExtMainAppList, ExtMainApp, M_POD_OPLIST)
|
||||
|
||||
ExtMainAppList_t* loader_get_ext_main_apps(Loader* loader);
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <flipper_application/flipper_application.h>
|
||||
#include "loader.h"
|
||||
#include "loader_menu.h"
|
||||
#include "loader_extmainapp.h"
|
||||
#include "loader_menuapp.h"
|
||||
#include "loader_applications.h"
|
||||
|
||||
typedef struct {
|
||||
@@ -20,7 +20,7 @@ struct Loader {
|
||||
LoaderMenu* loader_menu;
|
||||
LoaderApplications* loader_applications;
|
||||
LoaderAppData app;
|
||||
ExtMainAppList_t ext_main_apps;
|
||||
MenuAppList_t menu_apps;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include "loader.h"
|
||||
#include "loader_menu.h"
|
||||
#include "loader_extmainapp.h"
|
||||
#include "loader_menuapp.h"
|
||||
|
||||
#define TAG "LoaderMenu"
|
||||
|
||||
@@ -56,23 +56,9 @@ static void loader_menu_start(const char* name) {
|
||||
furi_record_close(RECORD_LOADER);
|
||||
}
|
||||
|
||||
static void loader_menu_apps_callback(void* context, uint32_t index) {
|
||||
static void loader_menu_callback(void* context, uint32_t index) {
|
||||
UNUSED(context);
|
||||
const char* name_or_path = (const char*)index;
|
||||
loader_menu_start(name_or_path);
|
||||
}
|
||||
|
||||
static void loader_menu_applications_callback(void* context, uint32_t index) {
|
||||
UNUSED(index);
|
||||
UNUSED(context);
|
||||
const char* name = LOADER_APPLICATIONS_NAME;
|
||||
loader_menu_start(name);
|
||||
}
|
||||
|
||||
static void loader_menu_settings_menu_callback(void* context, uint32_t index) {
|
||||
UNUSED(context);
|
||||
const char* name = FLIPPER_SETTINGS_APPS[index].name;
|
||||
loader_menu_start(name);
|
||||
loader_menu_start((const char*)index);
|
||||
}
|
||||
|
||||
static void loader_menu_switch_to_settings(void* context, uint32_t index) {
|
||||
@@ -96,43 +82,30 @@ static void loader_menu_build_menu(LoaderMenuApp* app, LoaderMenu* menu) {
|
||||
app->primary_menu,
|
||||
LOADER_APPLICATIONS_NAME,
|
||||
&A_Plugins_14,
|
||||
0,
|
||||
loader_menu_applications_callback,
|
||||
(uint32_t)LOADER_APPLICATIONS_NAME,
|
||||
loader_menu_callback,
|
||||
(void*)menu);
|
||||
for(size_t i = 0; i < FLIPPER_EXTERNAL_APPS_COUNT; i++) {
|
||||
menu_add_item(
|
||||
app->primary_menu,
|
||||
FLIPPER_EXTERNAL_APPS[i].name,
|
||||
FLIPPER_EXTERNAL_APPS[i].icon,
|
||||
(uint32_t)FLIPPER_EXTERNAL_APPS[i].name,
|
||||
loader_menu_apps_callback,
|
||||
(void*)menu);
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < FLIPPER_APPS_COUNT; i++) {
|
||||
menu_add_item(
|
||||
app->primary_menu,
|
||||
FLIPPER_APPS[i].name,
|
||||
FLIPPER_APPS[i].icon,
|
||||
(uint32_t)FLIPPER_APPS[i].name,
|
||||
loader_menu_apps_callback,
|
||||
(void*)menu);
|
||||
}
|
||||
menu_add_item(
|
||||
app->primary_menu, "Settings", &A_Settings_14, 0, loader_menu_switch_to_settings, app);
|
||||
Loader* loader = furi_record_open(RECORD_LOADER);
|
||||
ExtMainAppList_t* ext_main_apps = loader_get_ext_main_apps(loader);
|
||||
for(size_t i = 0; i < ExtMainAppList_size(*ext_main_apps); i++) {
|
||||
const ExtMainApp* ext_main_app = ExtMainAppList_get(*ext_main_apps, i);
|
||||
MenuAppList_t* menu_apps = loader_get_menu_apps(loader);
|
||||
for(size_t i = 0; i < MenuAppList_size(*menu_apps); i++) {
|
||||
const MenuApp* menu_app = MenuAppList_get(*menu_apps, i);
|
||||
menu_add_item(
|
||||
app->primary_menu,
|
||||
ext_main_app->name,
|
||||
ext_main_app->icon,
|
||||
(uint32_t)ext_main_app->path,
|
||||
loader_menu_apps_callback,
|
||||
menu_app->label,
|
||||
menu_app->icon,
|
||||
(uint32_t)menu_app->exe,
|
||||
loader_menu_callback,
|
||||
(void*)menu);
|
||||
}
|
||||
furi_record_close(RECORD_LOADER);
|
||||
|
||||
const FlipperExternalApplication* last =
|
||||
&FLIPPER_EXTERNAL_APPS[FLIPPER_EXTERNAL_APPS_COUNT - 1];
|
||||
menu_add_item(
|
||||
app->primary_menu, last->name, last->icon, (uint32_t)last->path, loader_menu_callback, app);
|
||||
menu_add_item(
|
||||
app->primary_menu, "Settings", &A_Settings_14, 0, loader_menu_switch_to_settings, app);
|
||||
};
|
||||
|
||||
static void loader_menu_build_submenu(LoaderMenuApp* app, LoaderMenu* loader_menu) {
|
||||
@@ -140,8 +113,8 @@ static void loader_menu_build_submenu(LoaderMenuApp* app, LoaderMenu* loader_men
|
||||
submenu_add_item(
|
||||
app->settings_menu,
|
||||
FLIPPER_SETTINGS_APPS[i].name,
|
||||
i,
|
||||
loader_menu_settings_menu_callback,
|
||||
(uint32_t)FLIPPER_SETTINGS_APPS[i].name,
|
||||
loader_menu_callback,
|
||||
loader_menu);
|
||||
}
|
||||
}
|
||||
|
||||
14
applications/services/loader/loader_menuapp.h
Normal file
14
applications/services/loader/loader_menuapp.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <gui/icon.h>
|
||||
#include <m-list.h>
|
||||
|
||||
typedef struct {
|
||||
const char* label;
|
||||
const Icon* icon;
|
||||
const char* exe;
|
||||
} MenuApp;
|
||||
|
||||
LIST_DEF(MenuAppList, MenuApp, M_POD_OPLIST)
|
||||
|
||||
MenuAppList_t* loader_get_menu_apps(Loader* loader);
|
||||
@@ -9,7 +9,8 @@ extern "C" {
|
||||
|
||||
#define XTREME_SETTINGS_PATH CFG_PATH("xtreme_settings.txt")
|
||||
#define XTREME_ASSETS_PATH EXT_PATH("dolphin_custom")
|
||||
#define XTREME_APPS_PATH CFG_PATH("xtreme_apps.txt")
|
||||
#define XTREME_MENU_OLD_PATH CFG_PATH("xtreme_apps.txt")
|
||||
#define XTREME_MENU_PATH CFG_PATH("xtreme_menu.txt")
|
||||
#define XTREME_ASSETS_PACK_NAME_LEN 32
|
||||
|
||||
typedef enum {
|
||||
|
||||
Reference in New Issue
Block a user