Launcher: Added fIle browser

It doesn't do anything yet other than allow to navigate the tree...
This commit is contained in:
Alex Duchesne 2025-03-17 13:40:09 -04:00
parent 83a1494bca
commit f4d9293b01
5 changed files with 214 additions and 1 deletions

View File

@ -1065,6 +1065,12 @@ char *rg_gui_file_picker(const char *title, const char *path, bool (*validator)(
return filepath;
}
char *rg_gui_input_str(const char *title, const char *message, const char *default_value)
{
// This will need to fully implement a proper virtual keyboard :(
return default_value ? strdup(default_value) : NULL;
}
void rg_gui_draw_keyboard(const rg_keyboard_map_t *map, size_t cursor)
{
RG_ASSERT_ARG(map);

View File

@ -119,7 +119,7 @@ intptr_t rg_gui_dialog(const char *title, const rg_gui_option_t *options, int se
bool rg_gui_confirm(const char *title, const char *message, bool default_yes);
void rg_gui_alert(const char *title, const char *message);
char *rg_gui_file_picker(const char *title, const char *path, bool (*validator)(const char *path), bool none_option);
char *rg_gui_prompt(const char *title, const char *message, const char *default_value);
char *rg_gui_input_str(const char *title, const char *message, const char *default_value);
int rg_gui_savestate_menu(const char *title, const char *rom_path);
void rg_gui_options_menu(void);

202
launcher/main/browser.c Normal file
View File

@ -0,0 +1,202 @@
#include <rg_system.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <errno.h>
#include "applications.h"
#include "gui.h"
typedef struct
{
char *name;
uint32_t size;
uint8_t type;
uint8_t _unused1;
uint8_t _unused2;
uint8_t _unused3;
} file_t;
static const char *current_path = NULL;
static file_t *files = NULL;
static size_t files_count = 0;
static size_t files_capacity = 0;
static int scan_folder_cb(const rg_scandir_t *entry, void *arg)
{
uint8_t type = RETRO_TYPE_INVALID;
if (entry->is_file)
{
type = RETRO_TYPE_FILE;
}
else if (entry->is_dir)
{
type = RETRO_TYPE_FOLDER;
}
if (type == RETRO_TYPE_INVALID)
return RG_SCANDIR_CONTINUE;
if (files_count + 1 > files_capacity)
{
size_t new_capacity = (files_capacity * 1.5) + 1;
file_t *new_buf = realloc(files, new_capacity * sizeof(file_t));
if (!new_buf)
return RG_SCANDIR_STOP;
files = new_buf;
files_capacity = new_capacity;
}
files[files_count++] = (file_t) {
.name = strdup(entry->basename),
.type = type,
};
return RG_SCANDIR_CONTINUE;
}
static void scan_folder(tab_t *tab, const char *path, const char *selection)
{
size_t items_count = 0;
for (size_t i = 0; i < files_count; ++i)
free(files[i].name);
current_path = rg_unique_string(path);
files_count = 0;
memset(&tab->status, 0, sizeof(tab->status));
tab->navpath = current_path;
rg_storage_scandir(current_path, scan_folder_cb, NULL, 0);
RG_LOGI("Found %d files", (int)files_count);
gui_resize_list(tab, files_count);
tab->listbox.cursor = 0;
for (size_t i = 0; i < files_count; i++)
{
file_t *file = &files[i];
if (file->type == RETRO_TYPE_INVALID || !file->name)
continue;
if (file->type == RETRO_TYPE_FOLDER)
{
listbox_item_t *item = &tab->listbox.items[items_count++];
snprintf(item->text, sizeof(item->text), "[%.40s]", file->name);
item->group = 1;
item->arg = file;
}
else if (file->type == RETRO_TYPE_FILE)
{
listbox_item_t *item = &tab->listbox.items[items_count++];
snprintf(item->text, sizeof(item->text), "%s", file->name);
item->group = 2;
item->arg = file;
}
}
gui_resize_list(tab, items_count);
gui_sort_list(tab);
if (selection)
{
for (int i = 0; i < tab->listbox.length; i++)
{
file_t *file = tab->listbox.items[i].arg;
if (file && strcmp(file->name, selection) == 0)
{
tab->listbox.cursor = i;
break;
}
}
}
gui_scroll_list(tab, SCROLL_SET, tab->listbox.cursor);
}
static void show_file_menu(const char *path)
{
rg_stat_t info = rg_storage_stat(path);
if (!info.exists)
{
rg_gui_alert(_("File not found"), path);
return;
}
const rg_gui_option_t options[] = {
{0, _("Open file with..."), NULL, 1, NULL},
{0, _("Rename file"), NULL, 1, NULL},
{0, _("Copy file"), NULL, 1, NULL},
{0, _("Move file"), NULL, 1, NULL},
{0, _("Delete file"), NULL, 1, NULL},
{0, _("Close"), NULL, 1, NULL},
RG_DIALOG_END,
};
rg_gui_dialog(rg_basename(path), options, -1);
}
static void event_handler(gui_event_t event, tab_t *tab)
{
listbox_item_t *item = gui_get_selected_item(tab);
file_t *file = (file_t *)(item ? item->arg : NULL);
if (event == TAB_INIT)
{
char *selection = file ? strdup(file->name) : NULL;
scan_folder(tab, current_path, selection);
free(selection);
}
else if (event == TAB_DEINIT)
{
//
}
else if (event == TAB_ENTER || event == TAB_LEAVE || event == TAB_SCROLL)
{
gui_set_status(tab, NULL, "");
gui_set_preview(tab, NULL);
tab->navpath = current_path;
}
else if (event == TAB_IDLE)
{
//
}
else if (event == TAB_ACTION)
{
if (file)
{
char pathbuf[RG_PATH_MAX + 1];
snprintf(pathbuf, RG_PATH_MAX, "%s/%s", current_path, file->name);
if (file->type == RETRO_TYPE_FOLDER)
scan_folder(tab, pathbuf, NULL);
else
show_file_menu(pathbuf);
}
}
else if (event == TAB_BACK)
{
if (current_path == rg_unique_string(RG_STORAGE_ROOT))
{
// Can't go higher than our storage root because esp-idf won't show anything
tab->navpath = NULL;
}
else
{
char *selection = strdup(rg_basename(current_path));
scan_folder(tab, rg_dirname(current_path), selection);
free(selection);
}
}
}
void browser_init(void)
{
current_path = rg_unique_string(RG_STORAGE_ROOT);
gui_add_tab("browser", "File Manager", NULL, event_handler);
}

3
launcher/main/browser.h Normal file
View File

@ -0,0 +1,3 @@
#pragma once
void browser_init(void);

View File

@ -11,6 +11,7 @@
#include "applications.h"
#include "bookmarks.h"
#include "browser.h"
#include "gui.h"
#include "webui.h"
#include "updater.h"
@ -202,6 +203,7 @@ static void retro_loop(void)
gui_init(app->isColdBoot);
applications_init();
bookmarks_init();
// browser_init();
#ifdef RG_ENABLE_NETWORKING
rg_network_init();