Archive: Add dynamic paths to browser tab (#322)

* feat(Archive): Adds dynamic paths to browser tab

I thought it would be cool to be able to see when I was in say the
`apps_data/flipchess` folder, or some other nested folder, and have
"flipchess" be shown rather than the just "Browser" all the time. It's
not a huge or really crucial change, just a personal modification that
some people may also find useful.

* fix(Archive): Clean up, built-ins, safer

Cleaned up `archive_update_formatted_path` function using switch case,
and also using the built in furi functions where possible. Also removed
the arbitrary and unnecessary `path_buf[256]`, making formatting the
path in the Brief section more memory safe.

* Rename setting and use setting_enum()

* Remove prev_path

* Enum names

* Single text draw call

* Rename to statusbar title

* Revert "Rename to statusbar title"

This reverts commit 243f2a754f.

* Revert "Single text draw call"

This reverts commit 3bbe30449b.

* Simpler fix

* Shorter setting label

* Update changelog

---------

Co-authored-by: Willy-JL <49810075+Willy-JL@users.noreply.github.com>
This commit is contained in:
Alexander Bays
2025-01-16 19:44:11 -06:00
committed by GitHub
parent f151527ffb
commit b9c0289847
7 changed files with 121 additions and 5 deletions

View File

@@ -7,6 +7,7 @@
- Apps:
- Games: Pinball0 (by @rdefeo)
- NFC: Metroflip (by @luu176)
- Archive: Setting to show dynamic path in file browser statusbar (#322 by @956MB)
- CLI: Add `clear` and `cls` commands, add `did you mean ...?` command suggestion (#342 by @dexvleads)
- Main Menu: Add coverflow menu style (#314 by @CodyTolene)
- BadKB: Added german Mac keyboard Layout (#325 by @Cloudy261)

View File

@@ -34,6 +34,7 @@ static void
model->list_offset = 0;
model->list_loading = true;
model->folder_loading = false;
browser->path_changed = true;
},
false);
archive_update_offset(browser);
@@ -556,6 +557,7 @@ void archive_switch_tab(ArchiveBrowserView* browser, InputKey key) {
archive_set_tab(browser, tab);
furi_string_set(browser->path, archive_get_default_path(tab));
browser->path_changed = true;
bool tab_empty = true;
bool is_app_tab = furi_string_start_with_str(browser->path, "/app:");
if(tab == ArchiveTabFavorites) {
@@ -644,6 +646,7 @@ void archive_leave_dir(ArchiveBrowserView* browser) {
size_t dirname_start = furi_string_search_rchar(browser->path, '/');
furi_string_left(browser->path, dirname_start);
browser->path_changed = true;
const char* switch_ext = NULL;
switch(archive_get_tab(browser)) {

View File

@@ -58,6 +58,58 @@ void archive_browser_set_callback(
browser->context = context;
}
static void archive_update_formatted_path(ArchiveBrowserViewModel* model) {
ArchiveBrowserView* browser = model->archive->browser;
if(!browser->path_changed) {
return;
}
if(momentum_settings.browser_path_mode == BrowserPathOff || archive_is_home(browser)) {
furi_string_set(browser->formatted_path, ArchiveTabNames[model->tab_idx]);
} else {
const char* path = furi_string_get_cstr(browser->path);
switch(momentum_settings.browser_path_mode) {
case BrowserPathFull:
furi_string_set(browser->formatted_path, browser->path);
break;
case BrowserPathBrief: {
furi_string_reset(browser->formatted_path);
FuriString* token = furi_string_alloc();
FuriString* remaining = furi_string_alloc_set(path);
while(furi_string_size(remaining) > 0) {
size_t slash_pos = furi_string_search_char(remaining, '/');
if(slash_pos == FURI_STRING_FAILURE) {
furi_string_cat_printf(
browser->formatted_path, "/%s", furi_string_get_cstr(remaining));
break;
}
furi_string_set_n(token, remaining, 0, slash_pos);
if(furi_string_size(token) > 0) {
furi_string_cat_printf(
browser->formatted_path, "/%c", furi_string_get_char(token, 0));
}
furi_string_right(remaining, slash_pos + 1);
}
furi_string_free(token);
furi_string_free(remaining);
break;
}
case BrowserPathCurrent:
path_extract_basename(path, browser->formatted_path);
break;
default:
break;
}
}
browser->path_changed = false;
}
static void render_item_menu(Canvas* canvas, ArchiveBrowserViewModel* model) {
if(menu_array_size(model->context_menu) == 0) {
// Need init context menu
@@ -275,10 +327,15 @@ static void draw_list(Canvas* canvas, ArchiveBrowserViewModel* model) {
static void archive_render_status_bar(Canvas* canvas, ArchiveBrowserViewModel* model) {
furi_assert(model);
const char* tab_name = ArchiveTabNames[model->tab_idx];
if(model->tab_idx == ArchiveTabSearch &&
scene_manager_get_scene_state(model->archive->scene_manager, ArchiveAppSceneSearch)) {
tab_name = "Searching";
const char* tab_name = NULL;
if(model->tab_idx == ArchiveTabSearch) {
if(scene_manager_get_scene_state(model->archive->scene_manager, ArchiveAppSceneSearch)) {
tab_name = "Searching";
} else {
tab_name = ArchiveTabNames[model->tab_idx];
}
} else {
archive_update_formatted_path(model);
}
bool clip = model->clipboard != NULL;
@@ -293,7 +350,19 @@ static void archive_render_status_bar(Canvas* canvas, ArchiveBrowserViewModel* m
canvas_draw_rframe(canvas, 0, 0, 51, 13, 1); // frame
canvas_draw_line(canvas, 49, 1, 49, 11); // shadow right
canvas_draw_line(canvas, 1, 11, 49, 11); // shadow bottom
canvas_draw_str_aligned(canvas, 25, 9, AlignCenter, AlignBottom, tab_name);
if(tab_name) {
canvas_draw_str_aligned(canvas, 25, 9, AlignCenter, AlignBottom, tab_name);
} else {
elements_scrollable_text_line_centered(
canvas,
25,
9,
45,
model->archive->browser->formatted_path,
model->scroll_counter,
false,
true);
}
if(clip) {
canvas_draw_rframe(canvas, 69, 0, 25, 13, 1);
@@ -593,6 +662,8 @@ ArchiveBrowserView* browser_alloc(void) {
browser->scroll_timer = furi_timer_alloc(browser_scroll_timer, FuriTimerTypePeriodic, browser);
browser->path = furi_string_alloc_set(archive_get_default_path(TAB_DEFAULT));
browser->formatted_path = furi_string_alloc();
browser->path_changed = true;
with_view_model(
browser->view,
@@ -626,6 +697,7 @@ void browser_free(ArchiveBrowserView* browser) {
false);
furi_string_free(browser->path);
furi_string_free(browser->formatted_path);
view_free(browser->view);
free(browser);

View File

@@ -3,6 +3,7 @@
#include "../helpers/archive_files.h"
#include "../helpers/archive_favorites.h"
#include "archive/archive.h"
#include <gui/gui_i.h>
#include <gui/view.h>
#include <gui/canvas.h>
@@ -88,6 +89,8 @@ struct ArchiveBrowserView {
ArchiveBrowserViewCallback callback;
void* context;
FuriString* path;
FuriString* formatted_path;
bool path_changed;
InputKey last_tab_switch_dir;
bool is_root;
FuriTimer* scroll_timer;

View File

@@ -7,6 +7,13 @@ enum VarItemListIndex {
VarItemListIndexFavoriteTimeout,
};
const char* const browser_path_names[BrowserPathModeCount] = {
"OFF",
"Current",
"Brief",
"Full",
};
void momentum_app_scene_interface_filebrowser_var_item_list_callback(void* context, uint32_t index) {
MomentumApp* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, index);
@@ -38,6 +45,15 @@ static void
app->save_settings = true;
}
static void
momentum_app_scene_interface_filebrowser_browser_path_mode_changed(VariableItem* item) {
MomentumApp* app = variable_item_get_context(item);
uint8_t index = variable_item_get_current_value_index(item);
variable_item_set_current_value_text(item, browser_path_names[index]);
momentum_settings.browser_path_mode = index;
app->save_settings = true;
}
static void momentum_app_scene_interface_filebrowser_favorite_timeout_changed(VariableItem* item) {
MomentumApp* app = variable_item_get_context(item);
uint32_t value = variable_item_get_current_value_index(item);
@@ -80,6 +96,16 @@ void momentum_app_scene_interface_filebrowser_on_enter(void* context) {
variable_item_set_current_value_index(item, momentum_settings.show_internal_tab);
variable_item_set_current_value_text(item, momentum_settings.show_internal_tab ? "ON" : "OFF");
item = variable_item_list_add(
var_item_list,
"Show Path",
BrowserPathModeCount,
momentum_app_scene_interface_filebrowser_browser_path_mode_changed,
app);
variable_item_set_current_value_index(item, momentum_settings.browser_path_mode);
variable_item_set_current_value_text(
item, browser_path_names[momentum_settings.browser_path_mode]);
item = variable_item_list_add(
var_item_list,
"Favorite Timeout",

View File

@@ -30,6 +30,7 @@ MomentumSettings momentum_settings = {
.sort_dirs_first = true, // ON
.show_hidden_files = false, // OFF
.show_internal_tab = false, // OFF
.browser_path_mode = BrowserPathOff, // OFF
.favorite_timeout = 0, // OFF
.dark_mode = false, // OFF
.rgb_backlight = false, // OFF
@@ -100,6 +101,7 @@ static const struct {
{setting_bool(sort_dirs_first)},
{setting_bool(show_hidden_files)},
{setting_bool(show_internal_tab)},
{setting_enum(browser_path_mode, BrowserPathModeCount)},
{setting_uint(favorite_timeout, 0, 60)},
{setting_bool(dark_mode)},
{setting_bool(rgb_backlight)},

View File

@@ -55,6 +55,14 @@ typedef union __attribute__((packed)) {
uint32_t value;
} ScreenFrameColor;
typedef enum {
BrowserPathOff,
BrowserPathCurrent,
BrowserPathBrief,
BrowserPathFull,
BrowserPathModeCount,
} BrowserPathMode;
typedef struct {
char asset_pack[ASSET_PACKS_NAME_LEN];
uint32_t anim_speed;
@@ -79,6 +87,7 @@ typedef struct {
bool sort_dirs_first;
bool show_hidden_files;
bool show_internal_tab;
BrowserPathMode browser_path_mode;
uint32_t favorite_timeout;
bool dark_mode;
bool rgb_backlight;