From 283ce80923007072a6f255366363153f3c5a020e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Boh=C3=A1=C4=8Dek?= Date: Tue, 29 Jun 2021 14:18:08 +0200 Subject: [PATCH] refactor: split browser window --- file-browser/include/file_browser_utils.h | 11 + file-browser/include/gui_list_table.h | 29 +++ file-browser/include/window_browser_items.h | 46 +++++ file-browser/src/file_browser_utils.c | 39 ++++ file-browser/src/gui_list_table.c | 37 ++++ file-browser/src/window_browser.c | 211 +++----------------- file-browser/src/window_browser_items.c | 92 +++++++++ 7 files changed, 282 insertions(+), 183 deletions(-) create mode 100644 file-browser/include/file_browser_utils.h create mode 100644 file-browser/include/gui_list_table.h create mode 100644 file-browser/include/window_browser_items.h create mode 100644 file-browser/src/file_browser_utils.c create mode 100644 file-browser/src/gui_list_table.c create mode 100644 file-browser/src/window_browser_items.c diff --git a/file-browser/include/file_browser_utils.h b/file-browser/include/file_browser_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..aa0dca07d456c79971c72e821fdab1c95758fc00 --- /dev/null +++ b/file-browser/include/file_browser_utils.h @@ -0,0 +1,11 @@ +#ifndef __FILE_BROWSER_UTILS_H__ +#define __FILE_BROWSER_UTILS_H__ + +#include "file_open.h" +#include "gui.h" +#include "font.h" + +void file_browser_handle_opened_file(opened_file_state_t opened, gui_t *gui, + font_t *font); + +#endif // __FILE_BROWSER_UTILS_H__ diff --git a/file-browser/include/gui_list_table.h b/file-browser/include/gui_list_table.h new file mode 100644 index 0000000000000000000000000000000000000000..8d1c3a489ff126d45f14cd252b31bf1d4a6ea715 --- /dev/null +++ b/file-browser/include/gui_list_table.h @@ -0,0 +1,29 @@ +#ifndef __GUI_LIST_TABLE_H__ +#define __GUI_LIST_TABLE_H__ + +#include "gui.h" +#include "file_access.h" +#include "renderer.h" +#include "font.h" +#include + +#define MAX_COLUMN_CHARS 200 + +typedef char *(*table_get_data_fn)(void *state, uint16_t column, char *buffer); + +typedef struct { + char **columns_names; + uint16_t *columns_widths; + uint16_t columns_count; + table_get_data_fn get_data; +} gui_table_t; + +bool table_render_item(gui_table_t *table_state, void *state, + renderer_t *renderer, font_t *font, int16_t beg_x, + int16_t beg_y, display_pixel_t color); +char *browser_get_column_data(void *state, uint16_t column, char *out); + +bool table_update_widths(gui_table_t *table, font_t *font, void *arr, + size_t item_size, uint32_t items_count); + +#endif // __GUI_LIST_TABLE_H__ diff --git a/file-browser/include/window_browser_items.h b/file-browser/include/window_browser_items.h new file mode 100644 index 0000000000000000000000000000000000000000..271d476109f3ca6653d64d769ddfc52136a0d0eb --- /dev/null +++ b/file-browser/include/window_browser_items.h @@ -0,0 +1,46 @@ +#ifndef __WINDOW_BROWSER_ITEMS_H__ +#define __WINDOW_BROWSER_ITEMS_H__ + +#include "gui_component_text.h" +#include "gui_list_table.h" +#include +#include "renderer.h" +#include "display_utils.h" +#include "gui_list_commands.h" +#include "file_access.h" + +#define COLUMNS_COUNT 4 +typedef struct { + bool running; + gui_t *gui; + + container_t *list_container; + component_t *line_component; + window_t *browser_window; + + font_t *font; + + gui_list_command_state_t click_state; + text_t text_state; + + directory_t *current_directory; + fileaccess_state_t state; + + gui_table_t table; + uint16_t column_widths[COLUMNS_COUNT]; +} browser_window_state_t; + +extern char *column_names[]; + +bool browser_window_list_render_item(void *state, uint32_t index, + renderer_t *renderer, int16_t beg_x, + int16_t beg_y, + display_pixel_t color); + +bool browser_window_list_render_header(void *state, uint32_t index, + renderer_t *renderer, + int16_t beg_x, int16_t beg_y, + display_pixel_t color); + +char *browser_get_column_data(void *state, uint16_t column, char *out); +#endif // __WINDOW_BROWSER_ITEMS_H__ diff --git a/file-browser/src/file_browser_utils.c b/file-browser/src/file_browser_utils.c new file mode 100644 index 0000000000000000000000000000000000000000..1c00bfbdae32a31439c2eafe5c062a5e1c47df02 --- /dev/null +++ b/file-browser/src/file_browser_utils.c @@ -0,0 +1,39 @@ +#include "file_browser_utils.h" +#include "dialog.h" + +#define STDERR_BUFFER_LENGTH 3000 + +void +file_browser_handle_opened_file(opened_file_state_t opened, gui_t *gui, + font_t *font) { + logger_t *logger = gui->logger; + if (opened.error != FILOPER_SUCCESS) { + fileaccess_log_error(logger, opened.error); + dialog_info_show(gui, font, "Could not open file", + fileaccess_get_error_text(opened.error)); + } else if (opened.executed) { + if (opened.ended_with_error) { + logger_error(logger, __FILE__, __FUNCTION__, __LINE__, + "Executed file returned unhealthy signal %d", + opened.executing_file.output_signal); + + char buff[STDERR_BUFFER_LENGTH]; + int chars_read = read(opened.executing_file.stderr_pipe[READ_END], buff, + STDERR_BUFFER_LENGTH); + buff[chars_read] = '\0'; + + logger_error(logger, __FILE__, __FUNCTION__, __LINE__, + "Returned stderr: %s", buff); + dialog_info_show(gui, font, "Exited with nonzero code", + buff); + } else { + logger_info(logger, __FILE__, __FUNCTION__, __LINE__, + "Successfully returned from executing file."); + } + + executing_file_destroy(&opened.executing_file); + } else { + logger_info(logger, __FILE__, __FUNCTION__, __LINE__, + "Successfully returned without executing anything."); + } +} diff --git a/file-browser/src/gui_list_table.c b/file-browser/src/gui_list_table.c new file mode 100644 index 0000000000000000000000000000000000000000..48529138e8078b390cebce9c857ff75d000dbe53 --- /dev/null +++ b/file-browser/src/gui_list_table.c @@ -0,0 +1,37 @@ +#include "gui_list_table.h" + +bool table_render_item(gui_table_t *table_state, void *state, + renderer_t *renderer, font_t *font, int16_t beg_x, + int16_t beg_y, display_pixel_t color) { + uint16_t offset = beg_x; + char tmp[MAX_COLUMN_CHARS]; + for (int i = 0; i < table_state->columns_count; i++) { + char *data = table_state->get_data(state, i, tmp); + renderer_write_string(renderer, offset, beg_y, 0, font, data, + color); + offset += table_state->columns_widths[i]; + } + return true; +} + +bool table_update_widths(gui_table_t *table, font_t *font, void *arr, size_t item_size, + uint32_t items_count) { + char tmp[MAX_COLUMN_CHARS]; + for (int i = 0; i < table->columns_count; i++) { + uint16_t max_size = font_measure_text(font, table->columns_names[i]).x; + for (int j = 0; j < items_count; j++) { + char *data = + browser_get_column_data(arr + item_size * i, i, tmp); + if (data == NULL) { + continue; + } + uint16_t current_size = font_measure_text(font, data).x; + + if (current_size > max_size) { + max_size = current_size; + } + } + table->columns_widths[i] = max_size + 50; + } + return true; +} diff --git a/file-browser/src/window_browser.c b/file-browser/src/window_browser.c index 6c33734ae0a94a0f27997b279e5bbaac09d33ea0..08976f2a94d37e719ecb1afe2e73c86d985b0cde 100644 --- a/file-browser/src/window_browser.c +++ b/file-browser/src/window_browser.c @@ -1,6 +1,8 @@ #include "window_browser.h" #include "dialog.h" +#include "file_browser_utils.h" #include "display_utils.h" +#include "gui_list_table.h" #include "file_access.h" #include "file_open.h" #include "font.h" @@ -17,45 +19,11 @@ #include "path.h" #include "renderer.h" #include "keyboard_const.h" +#include "window_browser_items.h" #include #include #include -#define COLUMNS_COUNT 4 -#define MAX_COLUMN_CHARS 200 -#define STDERR_BUFFER_LENGTH 3000 - -char *column_names[] ={"NAME", "TYPE", "SIZE", "MODIFIED"}; - -typedef struct { - bool running; - gui_t *gui; - - container_t *list_container; - component_t *line_component; - window_t *browser_window; - - font_t *font; - - gui_list_command_state_t click_state; - text_t text_state; - - directory_t *current_directory; - fileaccess_state_t state; - - uint16_t column_widths[COLUMNS_COUNT]; -} browser_window_state_t; - -static bool browser_window_list_render_item(void *state, uint32_t index, - renderer_t *renderer, int16_t beg_x, - int16_t beg_y, - display_pixel_t color); - -static bool browser_window_list_render_header(void *state, uint32_t index, - renderer_t *renderer, - int16_t beg_x, int16_t beg_y, - display_pixel_t color); - static void browser_window_item_clicked(container_t *container, void *state, uint32_t selected_index); @@ -63,8 +31,6 @@ static void *browser_window_construct(window_t *window, void *state); static bool browser_window_running(void *state); static void browser_window_job(void *state); -static char *browser_get_column_data(file_t *file, uint16_t column, char* out); - gui_container_info_t window_browser_containers[] = { {.type = CONT_TABLE, .payload.list = {.render_item_fn = browser_window_list_render_item, @@ -164,6 +130,11 @@ static void *browser_window_construct(window_t *window, void *state) { bstate->list_container = &window->containers[0]; bstate->browser_window = window; + bstate->table.columns_count = COLUMNS_COUNT; + bstate->table.columns_names = column_names; + bstate->table.columns_widths = bstate->column_widths; + bstate->table.get_data = browser_get_column_data; + bstate->click_state.container = bstate->list_container; bstate->click_state.state = state; bstate->click_state.clicked = browser_window_item_clicked; @@ -203,54 +174,14 @@ static void *browser_window_construct(window_t *window, void *state) { return state; } -static void browser_window_item_clicked(container_t *container, void *state, - uint32_t selected_index) { - - browser_window_state_t *bstate = (browser_window_state_t *)state; - if (bstate->gui->active_window != bstate->browser_window) { - return; - } - - logger_t *logger = bstate->gui->logger; - - file_t current_file = bstate->current_directory->files[selected_index]; - - if (current_file.type == FT_FILE) { - // open - logger_info(logger, __FILE__, __FUNCTION__, __LINE__, "Opening file %s", - current_file.name); - opened_file_state_t opened = file_open(¤t_file, browser_exec_options, bstate->state); - if (opened.error != FILOPER_SUCCESS) { - fileaccess_log_error(logger, opened.error); - dialog_info_show(bstate->gui, bstate->font, "Could not open file", fileaccess_get_error_text(opened.error)); - } else if (opened.executed) { - if (opened.ended_with_error) { - logger_error(logger, __FILE__, __FUNCTION__, __LINE__, - "Executed file returned unhealthy signal %d", opened.executing_file.output_signal); - - char buff[STDERR_BUFFER_LENGTH]; - int chars_read = read(opened.executing_file.stderr_pipe[READ_END], buff, STDERR_BUFFER_LENGTH); - buff[chars_read] = '\0'; - - logger_error(logger, __FILE__, __FUNCTION__, __LINE__, "Returned stderr: %s", buff); - dialog_info_show(bstate->gui, bstate->font, "Exited with nonzero code", buff); - } else { - logger_info(logger, __FILE__, __FUNCTION__, __LINE__, "Successfully returned from executing file."); - } - - executing_file_destroy(&opened.executing_file); - } else { - logger_info(logger, __FILE__, __FUNCTION__, __LINE__, - "Successfully returned without executing anything."); - } - } else if (current_file.type == FT_FOLDER || current_file.type == FT_OTHER) { +static void browser_window_handle_folder_clicked(browser_window_state_t *bstate, file_t *current_file, logger_t *logger) { rgb_led_set_timeout(bstate->gui->pheripherals->rgb_leds, LED_LEFT, 0, 100, 100, 300); rgb_led_set_timeout(bstate->gui->pheripherals->rgb_leds, LED_RIGHT, 0, 100, 100, 300); - char new_dir_path[path_join_memory_size(bstate->current_directory->path, current_file.name)]; - path_join(bstate->current_directory->path, current_file.name, new_dir_path); + char new_dir_path[path_join_memory_size(bstate->current_directory->path, current_file->name)]; + path_join(bstate->current_directory->path, current_file->name, new_dir_path); directory_or_error_t data = fileaccess_directory_list(bstate->state, new_dir_path); if (data.error) { @@ -266,48 +197,29 @@ static void browser_window_item_clicked(container_t *container, void *state, logger_info(logger, __FILE__, __FUNCTION__, __LINE__, "Opening directory %s", bstate->current_directory->path); } - } } -static bool browser_window_list_render_item(void *state, uint32_t index, - renderer_t *renderer, int16_t beg_x, - int16_t beg_y, - display_pixel_t color) { +static void browser_window_item_clicked(container_t *container, void *state, + uint32_t selected_index) { + browser_window_state_t *bstate = (browser_window_state_t *)state; - logger_t *logger = bstate->gui->logger; - if (index >= bstate->current_directory->files_count) { - logger_error(logger, __FILE__, __FUNCTION__, __LINE__, "Tried to reach item out of index"); - return false; - } - file_t file = bstate->current_directory->files[index]; - - uint16_t offset = beg_x; - char tmp[MAX_COLUMN_CHARS]; - for (int i = 0; i < COLUMNS_COUNT; i++) { - char *data = browser_get_column_data(&file, i, tmp); - renderer_write_string(renderer, offset, beg_y, 0, bstate->font, data, - color); - offset += bstate->column_widths[i]; + if (bstate->gui->active_window != bstate->browser_window) { + return; } - return true; -} + logger_t *logger = bstate->gui->logger; -static bool browser_window_list_render_header(void *state, uint32_t index, - renderer_t *renderer, - int16_t beg_x, int16_t beg_y, - display_pixel_t color) { - browser_window_state_t *bstate = (browser_window_state_t *)state; - renderer_render_rectangle(renderer, beg_x - 3, beg_y + bstate->font->size, - 10000, 1, color); + file_t current_file = bstate->current_directory->files[selected_index]; - uint16_t offset = beg_x; + if (current_file.type == FT_FILE) { + logger_info(logger, __FILE__, __FUNCTION__, __LINE__, "Opening file %s", + current_file.name); + opened_file_state_t opened = file_open(¤t_file, browser_exec_options, bstate->state); + file_browser_handle_opened_file(opened, bstate->gui, bstate->font); - for (int i = 0; i < COLUMNS_COUNT; i++) { - renderer_write_string(renderer, offset, beg_y, 0, bstate->font, column_names[i], color); - offset += bstate->column_widths[i]; + } else if (current_file.type == FT_FOLDER || current_file.type == FT_OTHER) { + browser_window_handle_folder_clicked(bstate, ¤t_file, logger); } - return true; } static bool browser_window_running(void *state) { @@ -318,22 +230,9 @@ static bool browser_window_running(void *state) { static void browser_window_job(void *state) { browser_window_state_t *bstate = (browser_window_state_t *)state; - char tmp[MAX_COLUMN_CHARS]; - for (int i = 0; i < COLUMNS_COUNT; i++) { - uint16_t max_size = font_measure_text(bstate->font, column_names[i]).x; - for (int j = 0; j < bstate->current_directory->files_count; j++) { - char *data = browser_get_column_data(&bstate->current_directory->files[j], i, tmp); - if (data == NULL) { - continue; - } - uint16_t current_size = font_measure_text(bstate->font, data).x; - - if (current_size > max_size) { - max_size = current_size; - } - } - bstate->column_widths[i] = max_size + 50; - } + table_update_widths(&bstate->table, bstate->font, + bstate->current_directory->files, sizeof(file_t), + bstate->current_directory->files_count); bstate->line_component->y = bstate->font->size + 5; bstate->list_container->y = bstate->line_component->y / 2; @@ -348,57 +247,3 @@ static void browser_window_job(void *state) { } } -#define KiB 1024ULL -#define MiB KiB*KiB -#define GiB KiB*KiB*KiB -#define TiB KiB*KiB*KiB*KiB - -static char *browser_get_column_data(file_t *file, uint16_t column, char *out) { - switch (column) { - case 0: - return file->name; - case 1: - switch (file->type) { - case FT_FILE: - return "FILE"; - case FT_FOLDER: - return "DIR"; - case FT_OTHER: - return "OTHER"; - case FT_UNKNOWN: - return "UNKNOWN"; - } - break; - case 2: - // get size - { - uint64_t size = file->size; - double transformed = size; - char *append = "B"; - - if (size > TiB) { - transformed /= TiB; - append = "TiB"; - } else if (size > GiB) { - transformed /= GiB; - append = "GiB"; - } else if (size > MiB) { - transformed /= MiB; - append = "MiB"; - } else if (size > KiB) { - transformed /= KiB; - append = "KiB"; - } - - sprintf(out, "%.2f %s", transformed, append); - return out; - } - case 3: - // date modified - - strftime(out, MAX_COLUMN_CHARS, "%c", localtime(&file->modify_time)); - return out; - } - - return NULL; -} diff --git a/file-browser/src/window_browser_items.c b/file-browser/src/window_browser_items.c new file mode 100644 index 0000000000000000000000000000000000000000..33a381cf04cbcfe26f07de248bb7453288ac26ef --- /dev/null +++ b/file-browser/src/window_browser_items.c @@ -0,0 +1,92 @@ +#include "window_browser_items.h" + +char *column_names[] = {"NAME", "TYPE", "SIZE", "MODIFIED"}; + +bool browser_window_list_render_item(void *state, uint32_t index, + renderer_t *renderer, int16_t beg_x, + int16_t beg_y, + display_pixel_t color) { + browser_window_state_t *bstate = (browser_window_state_t *)state; + logger_t *logger = bstate->gui->logger; + if (index >= bstate->current_directory->files_count) { + logger_error(logger, __FILE__, __FUNCTION__, __LINE__, "Tried to reach item out of index"); + return false; + } + file_t file = bstate->current_directory->files[index]; + + return table_render_item(&bstate->table, &file, renderer, bstate->font, beg_x, beg_y, + color); +} + +bool browser_window_list_render_header(void *state, uint32_t index, + renderer_t *renderer, + int16_t beg_x, int16_t beg_y, + display_pixel_t color) { + browser_window_state_t *bstate = (browser_window_state_t *)state; + renderer_render_rectangle(renderer, beg_x - 3, beg_y + bstate->font->size, + 10000, 1, color); + + uint16_t offset = beg_x; + + for (int i = 0; i < COLUMNS_COUNT; i++) { + renderer_write_string(renderer, offset, beg_y, 0, bstate->font, column_names[i], color); + offset += bstate->column_widths[i]; + } + return true; +} + +#define KiB 1024ULL +#define MiB KiB *KiB +#define GiB KiB *KiB *KiB +#define TiB KiB *KiB *KiB *KiB + +char *browser_get_column_data(void *state, uint16_t column, char *out) { + file_t *file = (file_t*)state; + switch (column) { + case 0: + return file->name; + case 1: + switch (file->type) { + case FT_FILE: + return "FILE"; + case FT_FOLDER: + return "DIR"; + case FT_OTHER: + return "OTHER"; + case FT_UNKNOWN: + return "UNKNOWN"; + } + break; + case 2: + // get size + { + uint64_t size = file->size; + double transformed = size; + char *append = "B"; + + if (size > TiB) { + transformed /= TiB; + append = "TiB"; + } else if (size > GiB) { + transformed /= GiB; + append = "GiB"; + } else if (size > MiB) { + transformed /= MiB; + append = "MiB"; + } else if (size > KiB) { + transformed /= KiB; + append = "KiB"; + } + + sprintf(out, "%.2f %s", transformed, append); + return out; + } + case 3: + // date modified + + strftime(out, MAX_COLUMN_CHARS, "%c", localtime(&file->modify_time)); + return out; + } + + return NULL; +}