Gui: scrollable long file names in FileBrowser and Archive Browser (#2159)

* Gui: scrollable long file names in FileBrowser
* Archive: scroll long file names
* Gui: elements code cleanup
This commit is contained in:
あく
2022-12-20 20:11:52 +09:00
committed by GitHub
parent 0286636183
commit e7107e39f7
7 changed files with 174 additions and 9 deletions

View File

@@ -19,6 +19,9 @@
#define CUSTOM_ICON_MAX_SIZE 32
#define SCROLL_INTERVAL (333)
#define SCROLL_DELAY (2)
typedef enum {
BrowserItemTypeLoading,
BrowserItemTypeBack,
@@ -95,6 +98,7 @@ struct FileBrowser {
void* item_context;
FuriString* result_path;
FuriTimer* scroll_timer;
};
typedef struct {
@@ -110,6 +114,7 @@ typedef struct {
const Icon* file_icon;
bool hide_ext;
size_t scroll_counter;
} FileBrowserModel;
static const Icon* BrowserItemIcons[] = {
@@ -129,6 +134,27 @@ static void
browser_list_item_cb(void* context, FuriString* item_path, bool is_folder, bool is_last);
static void browser_long_load_cb(void* context);
static void file_browser_scroll_timer_callback(void* context) {
furi_assert(context);
FileBrowser* browser = context;
with_view_model(
browser->view, FileBrowserModel * model, { model->scroll_counter++; }, true);
}
static void file_browser_view_enter_callback(void* context) {
furi_assert(context);
FileBrowser* browser = context;
with_view_model(
browser->view, FileBrowserModel * model, { model->scroll_counter = 0; }, true);
furi_timer_start(browser->scroll_timer, SCROLL_INTERVAL);
}
static void file_browser_view_exit_callback(void* context) {
furi_assert(context);
FileBrowser* browser = context;
furi_timer_stop(browser->scroll_timer);
}
FileBrowser* file_browser_alloc(FuriString* result_path) {
furi_assert(result_path);
FileBrowser* browser = malloc(sizeof(FileBrowser));
@@ -137,6 +163,11 @@ FileBrowser* file_browser_alloc(FuriString* result_path) {
view_set_context(browser->view, browser);
view_set_draw_callback(browser->view, file_browser_view_draw_callback);
view_set_input_callback(browser->view, file_browser_view_input_callback);
view_set_enter_callback(browser->view, file_browser_view_enter_callback);
view_set_exit_callback(browser->view, file_browser_view_exit_callback);
browser->scroll_timer =
furi_timer_alloc(file_browser_scroll_timer_callback, FuriTimerTypePeriodic, browser);
browser->result_path = result_path;
@@ -149,6 +180,8 @@ FileBrowser* file_browser_alloc(FuriString* result_path) {
void file_browser_free(FileBrowser* browser) {
furi_assert(browser);
furi_timer_free(browser->scroll_timer);
with_view_model(
browser->view, FileBrowserModel * model, { items_array_clear(model->items); }, false);
@@ -468,13 +501,17 @@ static void browser_draw_list(Canvas* canvas, FileBrowserModel* model) {
furi_string_set(filename, ". .");
}
elements_string_fit_width(
canvas, filename, (show_scrollbar ? MAX_LEN_PX - 6 : MAX_LEN_PX));
size_t scroll_counter = model->scroll_counter;
if(model->item_idx == idx) {
browser_draw_frame(canvas, i, show_scrollbar);
if(scroll_counter < SCROLL_DELAY) {
scroll_counter = 0;
} else {
scroll_counter -= SCROLL_DELAY;
}
} else {
canvas_set_color(canvas, ColorBlack);
scroll_counter = 0;
}
if(custom_icon_data) {
@@ -487,8 +524,14 @@ static void browser_draw_list(Canvas* canvas, FileBrowserModel* model) {
canvas_draw_icon(
canvas, 2, Y_OFFSET + 1 + i * FRAME_HEIGHT, BrowserItemIcons[item_type]);
}
canvas_draw_str(
canvas, 15, Y_OFFSET + 9 + i * FRAME_HEIGHT, furi_string_get_cstr(filename));
elements_scrollable_text_line(
canvas,
15,
Y_OFFSET + 9 + i * FRAME_HEIGHT,
(show_scrollbar ? MAX_LEN_PX - 6 : MAX_LEN_PX),
filename,
scroll_counter,
(model->item_idx != idx));
}
if(show_scrollbar) {
@@ -543,6 +586,7 @@ static bool file_browser_view_input_callback(InputEvent* event, void* context) {
file_browser_worker_load(
browser->worker, load_offset, ITEM_LIST_LEN_MAX);
}
model->scroll_counter = 0;
} else if(event->key == InputKeyDown) {
model->item_idx = (model->item_idx + 1) % model->item_cnt;
if(browser_is_list_load_required(model)) {
@@ -554,6 +598,7 @@ static bool file_browser_view_input_callback(InputEvent* event, void* context) {
file_browser_worker_load(
browser->worker, load_offset, ITEM_LIST_LEN_MAX);
}
model->scroll_counter = 0;
}
},
true);