feat: architectural improvements for Apps and System Configuration virtual folders in Files
This commit is contained in:
@@ -5,18 +5,9 @@
|
||||
*/
|
||||
|
||||
#include "filemanager_internal.hpp"
|
||||
#include <montauk/toml.h>
|
||||
|
||||
namespace filemanager {
|
||||
|
||||
static int filemanager_find_external_app(DesktopState* ds, const char* bin_path) {
|
||||
if (!ds || !bin_path) return -1;
|
||||
for (int x = 0; x < ds->external_app_count; x++) {
|
||||
if (montauk::streq(ds->external_apps[x].binary_path, bin_path)) return x;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void filemanager_reset_list_state(FileManagerState* fm) {
|
||||
fm->selected = -1;
|
||||
fm->scroll_offset = 0;
|
||||
@@ -29,8 +20,9 @@ static void filemanager_reset_virtual_entry(FileManagerVirtualEntry* entry) {
|
||||
if (!entry) return;
|
||||
entry->kind = FM_VIRTUAL_ENTRY_NONE;
|
||||
entry->external_app_index = -1;
|
||||
entry->builtin_id = DESKTOP_BUILTIN_NONE;
|
||||
entry->shared_applet_path[0] = '\0';
|
||||
montauk::memset(&entry->applet, 0, sizeof(entry->applet));
|
||||
entry->applet.kind = DESKTOP_APPLET_NONE;
|
||||
entry->applet.builtin_id = DESKTOP_BUILTIN_NONE;
|
||||
entry->icon_lg = {};
|
||||
entry->icon_sm = {};
|
||||
}
|
||||
@@ -49,14 +41,11 @@ static void filemanager_add_root_entry(FileManagerState* fm,
|
||||
fm->drive_indices[idx] = drive_index;
|
||||
}
|
||||
|
||||
static void filemanager_add_virtual_entry(FileManagerState* fm,
|
||||
const char* name,
|
||||
const char* icon_path,
|
||||
FileManagerVirtualEntryKind kind,
|
||||
int external_index,
|
||||
DesktopBuiltinId builtin_id,
|
||||
const char* shared_applet_path) {
|
||||
if (!fm || fm->entry_count >= 64) return;
|
||||
static int filemanager_add_virtual_entry(FileManagerState* fm,
|
||||
const char* name,
|
||||
const char* icon_path,
|
||||
FileManagerVirtualEntryKind kind) {
|
||||
if (!fm || fm->entry_count >= 64) return -1;
|
||||
|
||||
int idx = fm->entry_count;
|
||||
montauk::strncpy(fm->entry_names[idx], name, 63);
|
||||
@@ -66,13 +55,6 @@ static void filemanager_add_virtual_entry(FileManagerState* fm,
|
||||
fm->drive_indices[idx] = -1;
|
||||
filemanager_reset_virtual_entry(&fm->virtual_entries[idx]);
|
||||
fm->virtual_entries[idx].kind = kind;
|
||||
fm->virtual_entries[idx].external_app_index = external_index;
|
||||
fm->virtual_entries[idx].builtin_id = builtin_id;
|
||||
if (shared_applet_path && shared_applet_path[0]) {
|
||||
montauk::strncpy(fm->virtual_entries[idx].shared_applet_path,
|
||||
shared_applet_path,
|
||||
sizeof(fm->virtual_entries[idx].shared_applet_path));
|
||||
}
|
||||
|
||||
if (icon_path && icon_path[0]) {
|
||||
Color defColor = colors::ICON_COLOR;
|
||||
@@ -82,6 +64,27 @@ static void filemanager_add_virtual_entry(FileManagerState* fm,
|
||||
|
||||
fm->entry_count++;
|
||||
fm->virtual_entry_count = fm->entry_count;
|
||||
return idx;
|
||||
}
|
||||
|
||||
static void filemanager_add_external_app_entry(FileManagerState* fm,
|
||||
const ExternalApp& app,
|
||||
int external_index) {
|
||||
int idx = filemanager_add_virtual_entry(fm, app.name, app.icon_path,
|
||||
FM_VIRTUAL_ENTRY_EXTERNAL_APP);
|
||||
if (idx >= 0) {
|
||||
fm->virtual_entries[idx].external_app_index = external_index;
|
||||
}
|
||||
}
|
||||
|
||||
static void filemanager_add_system_configuration_applet_entry(
|
||||
FileManagerState* fm,
|
||||
const DesktopAppletEntry& applet) {
|
||||
int idx = filemanager_add_virtual_entry(fm, applet.label, applet.icon_path,
|
||||
FM_VIRTUAL_ENTRY_SYSTEM_CONFIGURATION_APPLET);
|
||||
if (idx >= 0) {
|
||||
fm->virtual_entries[idx].applet = applet;
|
||||
}
|
||||
}
|
||||
|
||||
static void filemanager_begin_virtual_view(FileManagerState* fm, FileManagerVirtualViewKind view) {
|
||||
@@ -126,7 +129,8 @@ void filemanager_read_drives(FileManagerState* fm) {
|
||||
}
|
||||
|
||||
// System configuration entry
|
||||
filemanager_add_root_entry(fm, "System Configuration", FM_ENTRY_SYSTEM_TOOLS_ROOT, -1);
|
||||
filemanager_add_root_entry(fm, "System Configuration",
|
||||
FM_ENTRY_SYSTEM_CONFIGURATION_ROOT, -1);
|
||||
|
||||
// Drive entries
|
||||
int drives[FM_MAX_DRIVES];
|
||||
@@ -292,7 +296,9 @@ void filemanager_free_app_icons(FileManagerState* fm) {
|
||||
void filemanager_read_virtual_view(FileManagerState* fm, FileManagerVirtualViewKind view) {
|
||||
switch (view) {
|
||||
case FM_VIRTUAL_VIEW_APPS: filemanager_read_apps(fm); break;
|
||||
case FM_VIRTUAL_VIEW_SYSTEM_TOOLS: filemanager_read_system_tools(fm); break;
|
||||
case FM_VIRTUAL_VIEW_SYSTEM_CONFIGURATION:
|
||||
filemanager_read_system_configuration(fm);
|
||||
break;
|
||||
default: filemanager_read_drives(fm); break;
|
||||
}
|
||||
}
|
||||
@@ -303,86 +309,20 @@ void filemanager_read_apps(FileManagerState* fm) {
|
||||
DesktopState* ds = fm->desktop;
|
||||
if (!ds) return;
|
||||
|
||||
// Scan manifests directly (like desktop_scan_apps but load icons at FM sizes)
|
||||
montauk::fmkdir("0:/apps");
|
||||
const char* entries[32];
|
||||
int count = montauk::readdir("0:/apps", entries, 32);
|
||||
|
||||
// Extract basenames from readdir results (strip "apps/" prefix)
|
||||
|
||||
/*
|
||||
TODO: Fix crash if 16-app ceiling is removed and remove ceiling
|
||||
*/
|
||||
for (int i = 0; i < count && fm->entry_count < 64; i++) {
|
||||
const char* raw = entries[i];
|
||||
// Strip "apps/" prefix
|
||||
if (raw[0] == 'a' && raw[1] == 'p' && raw[2] == 'p' && raw[3] == 's' && raw[4] == '/')
|
||||
raw += 5;
|
||||
char dirname[64];
|
||||
montauk::strncpy(dirname, raw, 63);
|
||||
int dlen = montauk::slen(dirname);
|
||||
if (dlen > 0 && dirname[dlen - 1] == '/') dirname[dlen - 1] = '\0';
|
||||
if (dirname[0] == '\0') continue;
|
||||
|
||||
// Open manifest
|
||||
char manifest_path[128];
|
||||
snprintf(manifest_path, 128, "0:/apps/%s/manifest.toml", dirname);
|
||||
int fh = montauk::open(manifest_path);
|
||||
if (fh < 0) continue;
|
||||
|
||||
uint64_t sz = montauk::getsize(fh);
|
||||
if (sz == 0 || sz > 4096) { montauk::close(fh); continue; }
|
||||
|
||||
char* text = (char*)montauk::malloc(sz + 1);
|
||||
montauk::read(fh, (uint8_t*)text, 0, sz);
|
||||
montauk::close(fh);
|
||||
text[sz] = '\0';
|
||||
|
||||
auto doc = montauk::toml::parse(text);
|
||||
montauk::mfree(text);
|
||||
|
||||
const char* name = doc.get_string("app.name", "Unknown");
|
||||
const char* binary = doc.get_string("app.binary", "");
|
||||
const char* icon_file = doc.get_string("app.icon", "");
|
||||
|
||||
char bin_path[128];
|
||||
snprintf(bin_path, 128, "0:/apps/%s/%s", dirname, binary);
|
||||
char icon_path[128];
|
||||
icon_path[0] = '\0';
|
||||
if (icon_file[0]) {
|
||||
snprintf(icon_path, 128, "0:/apps/%s/%s", dirname, icon_file);
|
||||
}
|
||||
|
||||
filemanager_add_virtual_entry(fm, name, icon_path,
|
||||
FM_VIRTUAL_ENTRY_EXTERNAL_APP,
|
||||
filemanager_find_external_app(ds, bin_path),
|
||||
DESKTOP_BUILTIN_NONE, nullptr);
|
||||
|
||||
doc.destroy();
|
||||
for (int i = 0; i < ds->external_app_count && fm->entry_count < 64; i++) {
|
||||
filemanager_add_external_app_entry(fm, ds->external_apps[i], i);
|
||||
}
|
||||
|
||||
filemanager_reset_list_state(fm);
|
||||
}
|
||||
|
||||
void filemanager_read_system_tools(FileManagerState* fm) {
|
||||
filemanager_begin_virtual_view(fm, FM_VIRTUAL_VIEW_SYSTEM_TOOLS);
|
||||
void filemanager_read_system_configuration(FileManagerState* fm) {
|
||||
filemanager_begin_virtual_view(fm, FM_VIRTUAL_VIEW_SYSTEM_CONFIGURATION);
|
||||
|
||||
int builtin_count = 0;
|
||||
const DesktopBuiltinEntry* builtins = desktop_builtin_registry(&builtin_count);
|
||||
for (int i = 0; i < builtin_count; i++) {
|
||||
if (!builtins[i].system_tools_applet) continue;
|
||||
filemanager_add_virtual_entry(fm, builtins[i].label, builtins[i].icon_path,
|
||||
FM_VIRTUAL_ENTRY_BUILTIN,
|
||||
-1, builtins[i].id, nullptr);
|
||||
}
|
||||
|
||||
DesktopSharedAppletEntry applets[32];
|
||||
DesktopAppletEntry applets[32];
|
||||
int applet_count = desktop_list_system_configuration_applets(fm->desktop, applets, 32);
|
||||
for (int i = 0; i < applet_count && fm->entry_count < 64; i++) {
|
||||
filemanager_add_virtual_entry(fm, applets[i].label, applets[i].icon_path,
|
||||
FM_VIRTUAL_ENTRY_SHARED_APPLET,
|
||||
-1, DESKTOP_BUILTIN_NONE,
|
||||
applets[i].library_path);
|
||||
filemanager_add_system_configuration_applet_entry(fm, applets[i]);
|
||||
}
|
||||
|
||||
filemanager_reset_list_state(fm);
|
||||
|
||||
Reference in New Issue
Block a user