#include "file_access.h" #include "file_browser_utils.h" #include "file_open.h" #include "font.h" #include "gui.h" #include "gui_component_text.h" #include "gui_component_line.h" #include "gui_list_commands.h" #include "gui_window_info.h" #include "renderer.h" #include #define CONTEXTMENU_OPEN_INDEX 0 #define CONTEXTMENU_OPEN_TEXT_INDEX 1 #define CONTEXTMENU_BACK_INDEX 2 typedef struct { bool running; gui_t *gui; fileaccess_state_t state; file_t *file; window_t *contextmenu_window; container_t *list_container; component_t *line_component; text_t name_state; font_t *font; gui_list_command_state_t click_state; } contextmenu_window_state_t; static bool contextmenu_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 contextmenu_window_item_clicked(container_t *container, void *state, uint32_t selected_index); static void *contextmenu_window_construct(window_t *window, void *state); static bool contextmenu_window_running(void *state); static void contextmenu_window_job(void *state); gui_container_info_t contextmenu_window_container_info[] = { {.type = CONT_TABLE, .payload.list = {.item_height = 16, .render_item_fn = contextmenu_window_list_render_item, .render_header_fn = NULL}}, {.type = CONT_GROUP, .payload.group.components_count = 2}}; window_info_t contextmenu_window_info = { .containers_count = 2, .containers = contextmenu_window_container_info, .construct = contextmenu_window_construct}; bool window_contextmenu_open(gui_t *gui, font_t *font, fileaccess_state_t state, file_t *file) { logger_t *logger = gui->logger; logger_info(logger, __FILE__, __FUNCTION__, __LINE__, "Opening initial window"); contextmenu_window_state_t cstate = { .running = true, .gui = gui, .font = font, .file = file, .state = state, }; uint16_t commands_state = commands_save_state(gui->commands); bool success = gui_window_init_and_loop(gui, &cstate, contextmenu_window_info, contextmenu_window_running, contextmenu_window_job); commands_restore_state(gui->commands, commands_state); logger_info(logger, __FILE__, __FUNCTION__, __LINE__, "Initial window closed"); return success; } static bool contextmenu_window_list_render_item(void *state, uint32_t index, renderer_t *renderer, int16_t beg_x, int16_t beg_y, display_pixel_t color) { contextmenu_window_state_t *cstate = (contextmenu_window_state_t *)state; char *data; switch (index) { case CONTEXTMENU_OPEN_INDEX: data = "OPEN"; break; case CONTEXTMENU_OPEN_TEXT_INDEX: data = "SHOW TEXT"; break; case CONTEXTMENU_BACK_INDEX: data = "BACK"; break; default: return false; } renderer_write_string(renderer, beg_x, beg_y, 0, cstate->font, data, color); return true; } static void contextmenu_window_item_clicked(container_t *container, void *state, uint32_t selected_index) { contextmenu_window_state_t *cstate = (contextmenu_window_state_t *)state; logger_t *logger = cstate->gui->logger; switch (selected_index) { case CONTEXTMENU_OPEN_INDEX: { logger_info(logger, __FILE__, __FUNCTION__, __LINE__, "Opening file"); opened_file_state_t opened = file_open(cstate->file, browser_exec_options, cstate->state); file_browser_handle_opened_file(opened, cstate->gui, cstate->font); } break; case CONTEXTMENU_OPEN_TEXT_INDEX: { logger_info(logger, __FILE__, __FUNCTION__, __LINE__, "Opening text"); opened_file_state_t opened = file_open_text(cstate->file, browser_exec_options, cstate->state); file_browser_handle_opened_file(opened, cstate->gui, cstate->font); } break; case CONTEXTMENU_BACK_INDEX: logger_info(logger, __FILE__, __FUNCTION__, __LINE__, "Going back"); cstate->running = false; break; default: break; } } static void command_handler_exit(void *state, int amount) { contextmenu_window_state_t *cstate = (contextmenu_window_state_t *)state; cstate->running = false; } static void *contextmenu_window_construct(window_t *window, void *state) { contextmenu_window_state_t *cstate = (contextmenu_window_state_t *)state; logger_t *logger = cstate->gui->logger; logger_info(logger, __FILE__, __FUNCTION__, __LINE__, "Constructing contextmenu window"); cstate->list_container = &window->containers[0]; cstate->contextmenu_window = window; cstate->click_state.container = cstate->list_container; cstate->click_state.state = state; cstate->click_state.clicked = contextmenu_window_item_clicked; cstate->click_state.font = cstate->font; cstate->click_state.gui = cstate->gui; cstate->click_state.window = window; cstate->name_state.font = cstate->font; cstate->name_state.line = cstate->file->name; cstate->name_state.color = WHITE_PIXEL; // containers init // group components init component_t path_text = gui_text_create(&cstate->name_state, 3, 3, cstate->gui->size.x, 0); component_t line_component = gui_line_create(&WHITE_PIXEL, 0, path_text.height + path_text.y + 3, 1000, 1); gui_group_container_add_component(&window->containers[1], path_text); cstate->line_component = gui_group_container_add_component(&window->containers[1], line_component); // list init gui_container_info_init(cstate->list_container, cstate, 3, 5, cstate->font->size / 2 + 3); cstate->list_container->width = cstate->gui->size.x - 20; cstate->list_container->height = cstate->gui->size.y - cstate->list_container->y - 20; // commands register gui_list_commands_register(cstate->gui->commands, &cstate->click_state); commands_register(cstate->gui->commands, IN_KEYBOARD, 'e', command_handler_exit, state); return state; } static bool contextmenu_window_running(void *state) { contextmenu_window_state_t *cstate = (contextmenu_window_state_t*)state; return cstate->running; } static void contextmenu_window_job(void *state) { contextmenu_window_state_t *cstate = (contextmenu_window_state_t *)state; cstate->line_component->y = cstate->font->size + 5; cstate->list_container->y = cstate->line_component->y / 2; gui_list_container_set_item_height(cstate->list_container, cstate->font->size); }