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:
@@ -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);
|
||||
|
Reference in New Issue
Block a user