From 1fecd26f0b654144cc814db90e81840fb6e2b9f1 Mon Sep 17 00:00:00 2001 From: Ross Gouldthorpe Date: Fri, 6 Dec 2024 23:10:25 +0000 Subject: [PATCH] big refactor refactored most of the history / favorite code to now be "bookkeeping". this now uses a common struct to hold the required paths and the record type (to open up future work for emus). --- Makefile | 1 + New Text Document.txt | 0 src/menu/actions.c | 8 +- src/menu/menu.c | 9 +- src/menu/menu_state.h | 11 +- src/menu/path.c | 10 + src/menu/path.h | 1 + src/menu/rom_history.c | 292 ++++++++++++----------------- src/menu/rom_history.h | 45 +++-- src/menu/ui_components.h | 13 ++ src/menu/ui_components/common.c | 81 +++++++- src/menu/ui_components/constants.h | 19 +- src/menu/ui_components/tabs.c | 15 ++ src/menu/views/browser.c | 24 +-- src/menu/views/favorite.c | 201 ++++++++++++-------- src/menu/views/load_disk.c | 28 +-- src/menu/views/load_rom.c | 12 +- src/menu/views/views.h | 3 + 18 files changed, 451 insertions(+), 322 deletions(-) create mode 100644 New Text Document.txt create mode 100644 src/menu/ui_components/tabs.c diff --git a/Makefile b/Makefile index f38d1d5b..1ea25e68 100644 --- a/Makefile +++ b/Makefile @@ -57,6 +57,7 @@ SRCS = \ menu/ui_components/common.c \ menu/ui_components/context_menu.c \ menu/ui_components/file_list.c \ + menu/ui_components/tabs.c \ menu/usb_comm.c \ menu/views/browser.c \ menu/views/credits.c \ diff --git a/New Text Document.txt b/New Text Document.txt new file mode 100644 index 00000000..e69de29b diff --git a/src/menu/actions.c b/src/menu/actions.c index 156f278b..659c134d 100644 --- a/src/menu/actions.c +++ b/src/menu/actions.c @@ -22,8 +22,8 @@ static void actions_clear (menu_t *menu) { menu->actions.options = false; menu->actions.settings = false; menu->actions.lz_context = false; - menu->actions.favorite = false; - menu->actions.load_last = false; + menu->actions.previous_tab = false; + menu->actions.next_tab = false; } static void actions_update_direction (menu_t *menu) { @@ -112,9 +112,9 @@ static void actions_update_buttons (menu_t *menu) { } else if (pressed.l || pressed.z) { menu->actions.lz_context = true; } else if (pressed.c_left) { - menu->actions.load_last = true; + menu->actions.previous_tab = true; } else if (pressed.c_right) { - menu->actions.favorite = true; + menu->actions.next_tab = true; } } diff --git a/src/menu/menu.c b/src/menu/menu.c index 6ec3b907..c8a86499 100644 --- a/src/menu/menu.c +++ b/src/menu/menu.c @@ -72,9 +72,9 @@ static void menu_init (boot_params_t *boot_params) { path_pop(path); path_push(path, MENU_HISTORY_FILE); - history_init(path_get(path)); - history_load(&menu->history); - menu->load.load_last = false; + bookkeeping_init(path_get(path)); + bookkeeping_load(&menu->history); + menu->load.load_history = -1; menu->load.load_favorite = -1; path_pop(path); @@ -158,7 +158,8 @@ static view_t menu_views[] = { { MENU_MODE_LOAD_EMULATOR, view_load_emulator_init, view_load_emulator_display }, { MENU_MODE_ERROR, view_error_init, view_error_display }, { MENU_MODE_FAULT, view_fault_init, view_fault_display }, - { MENU_MODE_FAVORITE, view_favorite_init, view_favorite_display } + { MENU_MODE_FAVORITE, view_favorite_init, view_favorite_display }, + { MENU_MODE_HISTORY, view_history_init, view_history_display } }; static view_t *menu_get_view (menu_mode_t id) { diff --git a/src/menu/menu_state.h b/src/menu/menu_state.h index 8d3a7b5c..2f4a3497 100644 --- a/src/menu/menu_state.h +++ b/src/menu/menu_state.h @@ -39,7 +39,8 @@ typedef enum { MENU_MODE_ERROR, MENU_MODE_FAULT, MENU_MODE_BOOT, - MENU_MODE_FAVORITE + MENU_MODE_FAVORITE, + MENU_MODE_HISTORY } menu_mode_t; /** @brief File entry type enumeration */ @@ -69,7 +70,7 @@ typedef struct { const char *storage_prefix; settings_t settings; - history_t history; + bookkeeping_t history; boot_params_t *boot_params; char *error_message; @@ -89,8 +90,8 @@ typedef struct { bool options; bool settings; bool lz_context; - bool favorite; - bool load_last; + bool previous_tab; + bool next_tab; } actions; struct { @@ -108,7 +109,7 @@ typedef struct { rom_info_t rom_info; path_t *disk_path; disk_info_t disk_info; - bool load_last; + int load_history; int load_favorite; } load; diff --git a/src/menu/path.c b/src/menu/path.c index bab60912..580aec06 100644 --- a/src/menu/path.c +++ b/src/menu/path.c @@ -149,4 +149,14 @@ bool path_has_value(path_t *path) { } } return false; +} + +bool path_are_match(path_t *left, path_t *right) { + if(!path_has_value(left) && !path_has_value(right)) { + return true; + } else if(path_has_value(left) && path_has_value(right)) { + return (strcmp(path_get(left), path_get(right)) == 0); + } else { + return false; + } } \ No newline at end of file diff --git a/src/menu/path.h b/src/menu/path.h index bc66e9c7..0b0f534c 100644 --- a/src/menu/path.h +++ b/src/menu/path.h @@ -34,5 +34,6 @@ char *path_ext_get (path_t *path); void path_ext_remove (path_t *path); void path_ext_replace (path_t *path, char *ext); bool path_has_value(path_t *path); +bool path_are_match(path_t *left, path_t *right); #endif diff --git a/src/menu/rom_history.c b/src/menu/rom_history.c index 93dc6b9b..a621d4e2 100644 --- a/src/menu/rom_history.c +++ b/src/menu/rom_history.c @@ -10,10 +10,10 @@ static char *history_path = NULL; static path_t* empty_path = NULL; -static history_t init; +static bookkeeping_t init; /** @brief Init history path */ -void history_init (char *path) { +void bookkeeping_init (char *path) { if (history_path) { free(history_path); } @@ -21,213 +21,151 @@ void history_init (char *path) { empty_path = path_create(""); } + +void bookkeeping_ini_load_list(bookkeeping_item_t* list, int count, mini_t* ini, const char* group) +{ + char buf[64]; + for(int i=0;ilast_rom = path_create(mini_get_string(ini, "history", "last_rom", "")); - history->last_disk = path_create(mini_get_string(ini, "history", "last_disk", "")); + bookkeeping_ini_load_list(history->history_items, HISTORY_COUNT, ini, "history"); + bookkeeping_ini_load_list(history->favorite_items, HISTORY_COUNT, ini, "favorite"); - char buffer[1024]; - - for(int i=0;ifavorites_rom[i] = path_create(buffer); -#else - sprintf(buffer,"%dfavorite_rom", i); - history->favorites_rom[i] = path_create(mini_get_string(ini, "favorite", buffer, "")); -#endif - } - - for(int i=0;ifavorites_disk[i] = path_create(buffer); -#else - sprintf(buffer,"%dfavorite_disk", i); - history->favorites_disk[i] = path_create(mini_get_string(ini, "favorite", buffer, "")); -#endif - } mini_free(ini); } +static void bookkeeping_ini_save_list(bookkeeping_item_t* list, int count, mini_t* ini, const char* group) +{ + char buf[64]; + for(int i=0;ilast_rom != NULL ? path_get(history->last_rom) : ""); - mini_set_string(ini, "history", "last_disk", history->last_disk != NULL ? path_get(history->last_disk) : ""); - - char buf[20]; - for(int i=0;ifavorites_rom[i]; - mini_set_string(ini, "favorite", buf, path != NULL ? path_get(path) : ""); - } - - for(int i=0;ifavorites_disk[i]; - mini_set_string(ini, "favorite", buf, path != NULL ? path_get(path) : ""); - } + bookkeeping_ini_save_list(history->history_items, HISTORY_COUNT, ini, "history"); + bookkeeping_ini_save_list(history->favorite_items, FAVORITES_COUNT, ini, "favorite"); mini_save(ini, MINI_FLAGS_SKIP_EMPTY_GROUPS); mini_free(ini); } - - -static void history_last_rom_update(history_t *history, path_t* path) { - if(history->last_rom != NULL) { - path_free(history->last_rom); - } - - if(path != NULL) { - history->last_rom = path_clone(path); - } else { - history->last_rom = path_create(""); - } -} - - -static void history_last_disk_update(history_t *history, path_t* path) { - if(history->last_disk != NULL) { - path_free(history->last_disk); - } - - if(path != NULL) { - history->last_disk = path_clone(path); - } else { - history->last_disk = path_create(""); - } -} - -void history_last_rom_set(history_t *history, path_t* disk_path, path_t* rom_path) -{ - history_last_rom_update(history, rom_path); - history_last_disk_update(history, disk_path); - - history_save(history); -} - -static void history_favorite_insert(history_t *history, int location, path_t* rom, path_t* disk) { - if(history->favorites_rom[location]) { - path_free(history->favorites_rom[location]); - } - if(history->favorites_disk[location]) { - path_free(history->favorites_disk[location]); - } - - history->favorites_rom[location] = rom != NULL ? path_clone(rom) : path_create(""); - history->favorites_disk[location] = rom != NULL ? path_clone(disk) : path_create(""); -} - - -static void history_favorite_replace(history_t *history, int toReplace, path_t* rom, path_t* disk) { - if(history->favorites_rom[toReplace]) { - path_free(history->favorites_rom[toReplace]); - history->favorites_rom[toReplace] = NULL; - } - if(rom != NULL) { - history->favorites_rom[toReplace] = path_clone(rom); - } - - if(history->favorites_disk[toReplace]) { - path_free(history->favorites_disk[toReplace]); - history->favorites_disk[toReplace] = NULL; - } - if(disk != NULL) { - history->favorites_disk[toReplace] = path_clone(disk); - } -} - -static void history_favorite_rotate(history_t *history) -{ - for(int i=1;ifavorites_rom[i], history->favorites_disk[i]); - } - - history_favorite_replace(history, FAVORITES_COUNT -1, NULL, NULL); -} - -static bool history_favorite_check_match(path_t* left, path_t* right) { - bool matches = false; - if(left == NULL && right == NULL) { - matches = true; - } else { - if(left != NULL && right != NULL) { - matches = (strcmp(path_get(left), path_get(right)) == 0); - } - } - - return matches; -} - -static bool history_favorite_exists(history_t *history, path_t* rom, path_t* disk) { - for(int i=0;ifavorites_rom[i], rom); - bool diskMatch = history_favorite_check_match(history->favorites_disk[i], disk); - - if(romMatch && diskMatch) { - return true; - } +static bool bookkeeping_item_match(bookkeeping_item_t* left, bookkeeping_item_t* right) { + if(left != NULL && right != NULL) { + return path_are_match(left->primary_path, right->primary_path) && path_are_match(left->secondary_path, right->secondary_path) && left->bookkeeping_type == right->bookkeeping_type; } return false; } -void history_favorite_add(history_t *history, path_t* rom, path_t* disk) { - // if the game is already in the favorite list then don't add again - - if(rom == NULL) { - rom = empty_path; +static void bookkeeping_clear_item(bookkeeping_item_t* item) { + if(item->primary_path != NULL){ + path_free(item->primary_path); } - if(disk == NULL) { - disk = empty_path; + if(item->secondary_path != NULL){ + path_free(item->secondary_path); } + item->bookkeeping_type = HISTORY_TYPE_EMPTY; +} - if(history_favorite_exists(history, rom, disk)) { +static void bookkeeping_copy_item(bookkeeping_item_t* source, bookkeeping_item_t* destination){ + bookkeeping_clear_item(destination); + + destination->primary_path = path_clone(source->primary_path); + destination->secondary_path = source->secondary_path != NULL ? path_clone(source->secondary_path) : path_create(""); + destination->bookkeeping_type = source->bookkeeping_type; +} + +static void bookkeeping_move_items_down(bookkeeping_item_t* list, int start, int end) { + int current = end; + + do { + if(current <= start || current < 0) { + break; + } + + bookkeeping_copy_item(&list[current - 1], &list[current]); + current--; + } while(true); +} + + + +static void bookkeeping_insert_top(bookkeeping_item_t* list, int count, bookkeeping_item_t* new_item) { + // if it matches the top of the list already then nothing to do + if(bookkeeping_item_match(&list[0], new_item)) { return; } - // look for a free space in the list - int place = -1; - for(int i=0;i < FAVORITES_COUNT;i++) { - if(!(path_has_value(history->favorites_rom[i]) || path_has_value(history->favorites_disk[i]))) { - place = i; - break; + // if the top isn't empty then we need to move things around + if(list[0].bookkeeping_type != HISTORY_TYPE_EMPTY) { + int found_at = -1; + for(int i=1; i < count; i++) { + if(bookkeeping_item_match(&list[i], new_item)){ + found_at = i; + break; + } + } + + if(found_at == -1) { + bookkeeping_move_items_down(list, 0, count - 1); + } else { + bookkeeping_move_items_down(list, 0, found_at); } } - - // if no free space then rotate the favorite list (first in first out) - // and set the place to add at the end of the list - if(place == -1) { - history_favorite_rotate(history); - place = FAVORITES_COUNT - 1; - } - - history_favorite_insert(history, place, rom, disk); - history_save(history); + + bookkeeping_copy_item(new_item, &list[0]); } -void history_favorite_remove(history_t *history, int location) -{ - if(location >= 0 && location < FAVORITES_COUNT) { - if(path_has_value(history->favorites_rom[location])) { - path_free(history->favorites_rom[location]); - history->favorites_rom[location] = path_create(""); - } - - if(path_has_value(history->favorites_disk[location])) { - path_free(history->favorites_disk[location]); - history->favorites_disk[location] = path_create(""); - } - } +void bookkeeping_history_add(bookkeeping_t *bookkeeping, path_t* primary_path, path_t* secondary_path, bookkeeping_item_types_t type ) { + bookkeeping_item_t new_item = { + .primary_path = primary_path, + .secondary_path = secondary_path, + .bookkeeping_type = type + }; + + bookkeeping_insert_top(bookkeeping->history_items, HISTORY_COUNT, &new_item); + bookkeeping_save(bookkeeping); +} + + +void bookkeeping_favorite_add(bookkeeping_t *bookkeeping, path_t* primary_path, path_t* secondary_path, bookkeeping_item_types_t type ) { + bookkeeping_item_t new_item = { + .primary_path = primary_path, + .secondary_path = secondary_path, + .bookkeeping_type = type + }; + + bookkeeping_insert_top(bookkeeping->favorite_items, FAVORITES_COUNT, &new_item); + bookkeeping_save(bookkeeping); } \ No newline at end of file diff --git a/src/menu/rom_history.h b/src/menu/rom_history.h index ecbf7d8f..0860bfe1 100644 --- a/src/menu/rom_history.h +++ b/src/menu/rom_history.h @@ -9,27 +9,48 @@ #include "path.h" + #define FAVORITES_COUNT 5 +#define HISTORY_COUNT 5 + +typedef enum { + HISTORY_TYPE_EMPTY, + HISTORY_TYPE_ROM, + HISTORY_TYPE_DISK, +} bookkeeping_item_types_t; -/** @brief Settings Structure */ typedef struct { - path_t* last_rom; - path_t* last_disk; + path_t* primary_path; + path_t* secondary_path; + + bookkeeping_item_types_t bookkeeping_type; + +} bookkeeping_item_t; + +/** @brief history Structure */ +typedef struct { + bookkeeping_item_t history_items[HISTORY_COUNT]; + + bookkeeping_item_t favorite_items[HISTORY_COUNT]; +} bookkeeping_t; - path_t* favorites_rom[FAVORITES_COUNT]; - path_t* favorites_disk[FAVORITES_COUNT]; -} history_t; /** @brief Init history path */ -void history_init (char *path); +void bookkeeping_init (char *path); + /** @brief The history to load */ -void history_load (history_t *history); +void bookkeeping_load (bookkeeping_t *history); + /** @brief The history to save */ -void history_save (history_t *history); +void bookkeeping_save (bookkeeping_t *history); -void history_last_rom_set(history_t *history, path_t* disk_path, path_t* rom_path); +//void history_last_rom_set(bookkeeping_t *history, path_t* disk_path, path_t* rom_path); -void history_favorite_add(history_t *history, path_t* rom, path_t* disk); -void history_favorite_remove(history_t *history, int location); +//void history_favorite_add(bookkeeping_t *history, path_t* rom, path_t* disk); +//void history_favorite_remove(bookkeeping_t *history, int location); + + +void bookkeeping_history_add(bookkeeping_t *bookkeeping, path_t* primary_path, path_t* secondary_path, bookkeeping_item_types_t type ); +void bookkeeping_favorite_add(bookkeeping_t *bookkeeping, path_t* primary_path, path_t* secondary_path, bookkeeping_item_types_t type ); #endif \ No newline at end of file diff --git a/src/menu/ui_components.h b/src/menu/ui_components.h index b80cd081..ed88e42c 100644 --- a/src/menu/ui_components.h +++ b/src/menu/ui_components.h @@ -253,5 +253,18 @@ void ui_components_boxart_free(component_boxart_t *b); void ui_components_boxart_draw(component_boxart_t *b); +/** + * + */ void ui_components_main_text_draw_location (float x, float y, char *fmt, ...); + +/** + * + */ +void ui_components_tabs_draw(const char** text, int count, int selected ); + +/** + * + */ +void ui_compontents_tabs_common_draw(int selected); #endif /* UI_COMPONENTS_H__ */ diff --git a/src/menu/ui_components/common.c b/src/menu/ui_components/common.c index 47d5efb1..3ff1c90d 100644 --- a/src/menu/ui_components/common.c +++ b/src/menu/ui_components/common.c @@ -13,9 +13,10 @@ void ui_components_box_draw (int x0, int y0, int x1, int y1, color_t color) { rdpq_mode_pop(); } -void ui_components_border_draw (int x0, int y0, int x1, int y1) { + +static void ui_components_border_draw_interal (int x0, int y0, int x1, int y1, color_t color) { rdpq_mode_push(); - rdpq_set_mode_fill(BORDER_COLOR); + rdpq_set_mode_fill(color); rdpq_fill_rectangle(x0 - BORDER_THICKNESS, y0 - BORDER_THICKNESS, x1 + BORDER_THICKNESS, y0); rdpq_fill_rectangle(x0 - BORDER_THICKNESS, y1, x1 + BORDER_THICKNESS, y1 + BORDER_THICKNESS); @@ -25,6 +26,10 @@ void ui_components_border_draw (int x0, int y0, int x1, int y1) { rdpq_mode_pop(); } +void ui_components_border_draw (int x0, int y0, int x1, int y1) { + ui_components_border_draw_interal(x0, y0, x1, y1, BORDER_COLOR); +} + void ui_components_layout_draw (void) { ui_components_border_draw( VISIBLE_AREA_X0, @@ -215,8 +220,10 @@ void ui_components_main_text_draw_location (float x, float y, char *fmt, ...) { .line_spacing = TEXT_LINE_SPACING_ADJUST, }, FNT_DEFAULT, - VISIBLE_AREA_X0 + TEXT_MARGIN_HORIZONTAL + x, - VISIBLE_AREA_Y0 + TEXT_MARGIN_VERTICAL + TEXT_OFFSET_VERTICAL + y, + x, + y, + ///VISIBLE_AREA_X0 + TEXT_MARGIN_HORIZONTAL + x, + //VISIBLE_AREA_Y0 + TEXT_MARGIN_VERTICAL + TEXT_OFFSET_VERTICAL + y, formatted, nbytes ); @@ -225,3 +232,69 @@ void ui_components_main_text_draw_location (float x, float y, char *fmt, ...) { free(formatted); } } + + +void ui_components_tabs_draw(const char** text, int count, int selected ) { + + ui_components_box_draw( + VISIBLE_AREA_X0, + LAYOUT_ACTIONS_SEPARATOR_Y, + VISIBLE_AREA_X1, + LAYOUT_ACTIONS_SEPARATOR_Y + BORDER_THICKNESS, + BORDER_COLOR + ); + + int x = VISIBLE_AREA_X0; + int y = OVERSCAN_HEIGHT; + int width = 14 * 8; + int height = TAB_HEIGHT; + + // first draw the tabs that are not selected + for(int i=0;i< count;i++) { + if(i != selected) { + + ui_components_box_draw( + x, + y, + x + width, + y + height, + TAB_INACTIVE_BACKGROUND_COLOR + ); + + ui_components_border_draw_interal( + x, + y, + x + width, + y + height, + TAB_INACTIVE_BORDER_COLOR + ); + + ui_components_main_text_draw_location(x + 8, y, (char*)text[i]); + } + + x += width; + } + // draw the selected tab + + if(selected >= 0 && selected < count) { + x = VISIBLE_AREA_X0 + (width * selected); + + ui_components_box_draw( + x, + y, + x + width, + y + height, + TAB_ACTIVE_BACKGROUND_COLOR + ); + + ui_components_border_draw_interal( + x, + y, + x + width, + y + height, + TAB_ACTIVE_BORDER_COLOR + ); + + ui_components_main_text_draw_location(x + 8, y, (char*)text[selected]); + } +} diff --git a/src/menu/ui_components/constants.h b/src/menu/ui_components/constants.h index c468a327..7074c078 100644 --- a/src/menu/ui_components/constants.h +++ b/src/menu/ui_components/constants.h @@ -7,6 +7,10 @@ #ifndef COMPONENTS_CONSTANTS_H__ #define COMPONENTS_CONSTANTS_H__ +#define TAB_HEIGHT (20) +/** @brief The thickness of borders. */ +#define BORDER_THICKNESS (4) + /** @brief The display width. */ #define DISPLAY_WIDTH (640) /** @brief The display height. */ @@ -25,7 +29,7 @@ /** @brief The start position of the visible display on the X axis. */ #define VISIBLE_AREA_X0 (OVERSCAN_WIDTH) /** @brief The start position of the visible display on the Y axis. */ -#define VISIBLE_AREA_Y0 (OVERSCAN_HEIGHT) +#define VISIBLE_AREA_Y0 (OVERSCAN_HEIGHT + TAB_HEIGHT + BORDER_THICKNESS) /** @brief The end position of the visible display on the X axis. */ #define VISIBLE_AREA_X1 (DISPLAY_WIDTH - OVERSCAN_WIDTH) /** @brief The end position of the visible display on the Y axis. */ @@ -36,8 +40,7 @@ /** @brief The height of the visible display. */ #define VISIBLE_AREA_HEIGHT (VISIBLE_AREA_Y1 - VISIBLE_AREA_Y0) -/** @brief The thickness of borders. */ -#define BORDER_THICKNESS (4) + #define LAYOUT_ACTIONS_SEPARATOR_Y (400) @@ -101,14 +104,14 @@ /** @brief The scroll bar width. */ #define LIST_SCROLLBAR_WIDTH (12) /** @brief The scroll bar height. */ -#define LIST_SCROLLBAR_HEIGHT (LAYOUT_ACTIONS_SEPARATOR_Y - OVERSCAN_HEIGHT) +#define LIST_SCROLLBAR_HEIGHT (LAYOUT_ACTIONS_SEPARATOR_Y - OVERSCAN_HEIGHT - TAB_HEIGHT) /** @brief The scroll bar position on the X axis. */ #define LIST_SCROLLBAR_X (VISIBLE_AREA_X1 - LIST_SCROLLBAR_WIDTH) /** @brief The scroll bar position on the Y axis. */ #define LIST_SCROLLBAR_Y (VISIBLE_AREA_Y0) /** @brief The maximum amount of file list entries. */ -#define LIST_ENTRIES (19) +#define LIST_ENTRIES (18) /** @brief The maximum width available for a file list entry. */ #define FILE_LIST_MAX_WIDTH (480) #define FILE_LIST_HIGHLIGHT_WIDTH (VISIBLE_AREA_X1 - VISIBLE_AREA_X0 - LIST_SCROLLBAR_WIDTH) @@ -147,4 +150,10 @@ #define CONTEXT_MENU_HIGHLIGHT_COLOR RGBA32(0x3F, 0x3F, 0x3F, 0xFF) +#define TAB_INACTIVE_BORDER_COLOR RGBA32(0x5F, 0x5F, 0x5F, 0xFF) +#define TAB_ACTIVE_BORDER_COLOR RGBA32(0x00, 0x00, 0xFF, 0xFF) + +#define TAB_INACTIVE_BACKGROUND_COLOR RGBA32(0x3F, 0x3F, 0x3F, 0xFF) +#define TAB_ACTIVE_BACKGROUND_COLOR RGBA32(0x6F, 0x6F, 0x6F, 0xFF) + #endif diff --git a/src/menu/ui_components/tabs.c b/src/menu/ui_components/tabs.c new file mode 100644 index 00000000..4b7470bd --- /dev/null +++ b/src/menu/ui_components/tabs.c @@ -0,0 +1,15 @@ +#include "../ui_components.h" + + + +static const char* tabs[3] = +{ + "Browser", + "History", + "Favorites" +}; + +void ui_compontents_tabs_common_draw(int selected) +{ + ui_components_tabs_draw(tabs, 3, selected); +} \ No newline at end of file diff --git a/src/menu/views/browser.c b/src/menu/views/browser.c index f88e6180..ae694dbe 100644 --- a/src/menu/views/browser.c +++ b/src/menu/views/browser.c @@ -358,32 +358,24 @@ static void process (menu_t *menu) { } else if (menu->actions.settings) { ui_components_context_menu_show(&settings_context_menu); sound_play_effect(SFX_SETTING); - } else if (menu->actions.favorite) { + } else if (menu->actions.next_tab) { + menu->next_mode = MENU_MODE_HISTORY; + } else if (menu->actions.previous_tab) { menu->next_mode = MENU_MODE_FAVORITE; - sound_play_effect(SFX_ENTER); - } else if (menu->actions.load_last) { - if(path_has_value(menu->history.last_disk)) { - menu->load.load_last = true; - menu->next_mode = MENU_MODE_LOAD_DISK; - sound_play_effect(SFX_ENTER); - } else if (path_has_value(menu->history.last_rom)) { - menu->load.load_last = true; - menu->next_mode = MENU_MODE_LOAD_ROM; - sound_play_effect(SFX_ENTER); - } } } - static void draw (menu_t *menu, surface_t *d) { rdpq_attach(d, NULL); ui_components_background_draw(); - ui_components_layout_draw(); + ui_components_layout_draw(); ui_components_file_list_draw(menu->browser.list, menu->browser.entries, menu->browser.selected); + ui_compontents_tabs_common_draw(0); + const char *action = NULL; if (menu->browser.entry) { @@ -417,14 +409,14 @@ static void draw (menu_t *menu, surface_t *d) { ui_components_actions_bar_text_draw( ALIGN_CENTER, VALIGN_TOP, "%s" //ctime includes a newline - " Favorite", + "", ctime(&menu->current_time) ); } else { ui_components_actions_bar_text_draw( ALIGN_CENTER, VALIGN_TOP, "\n" - " Favorite" + "" ); } diff --git a/src/menu/views/favorite.c b/src/menu/views/favorite.c index ff29dac2..8d848b5c 100644 --- a/src/menu/views/favorite.c +++ b/src/menu/views/favorite.c @@ -5,99 +5,139 @@ #include "../ui_components/constants.h" #include "../sound.h" -static int selected_favorite = -1; -static void favorite_reset_selected(menu_t* menu) { - selected_favorite = -1; +typedef enum { + BOOKKEEPING_SCREEN_MODE_HISTORY, + BOOKKEEPING_SCREEN_MODE_FAVORITE +} bookkeeping_screen_modes_t; - for(int i=0;ihistory.favorites_rom[i]) || path_has_value(menu->history.favorites_disk[i])) { - selected_favorite = i; +static bookkeeping_screen_modes_t screen_mode = -1; +static int selected_item = -1; +static bookkeeping_item_t* item_list; +static int item_max; + + +static void reset_selected(menu_t* menu) { + selected_item = -1; + + for(int i=0;i= item_max) { + selected_item = last; + break; + } else if(item_list[selected_item].bookkeeping_type != HISTORY_TYPE_EMPTY) { + sound_play_effect(SFX_CURSOR); + break; + } + } while (true); +} + +static void move_back() { + int last = selected_item; + do + { + selected_item--; + + if(selected_item < 0) { + selected_item = last; + break; + } else if(item_list[selected_item].bookkeeping_type != HISTORY_TYPE_EMPTY) { + sound_play_effect(SFX_CURSOR); + break; + } + } while (true); +} + static void process(menu_t* menu) { - if (menu->actions.back) { - menu->next_mode = MENU_MODE_BROWSER; - } else if(menu->actions.go_down) { - int last_favorite = selected_favorite; - - do - { - selected_favorite++; - - if(selected_favorite >= FAVORITES_COUNT) { - selected_favorite = last_favorite; - break; - } else if(path_has_value(menu->history.favorites_rom[selected_favorite]) || path_has_value(menu->history.favorites_disk[selected_favorite])) { - sound_play_effect(SFX_CURSOR); - break; - } - } while (true); + if(menu->actions.go_down) { + move_next(); } else if(menu->actions.go_up) { - int last_favorite = selected_favorite; + move_back(); + } else if(menu->actions.enter && selected_item != -1) { + + if(screen_mode == BOOKKEEPING_SCREEN_MODE_FAVORITE) { + menu->load.load_favorite = selected_item; + } else if(screen_mode == BOOKKEEPING_SCREEN_MODE_HISTORY) { + menu->load.load_history = selected_item; + } - do - { - selected_favorite--; - - if(selected_favorite < 0) { - selected_favorite = last_favorite; - break; - } else if(path_has_value(menu->history.favorites_rom[selected_favorite]) || path_has_value(menu->history.favorites_disk[selected_favorite])) { - sound_play_effect(SFX_CURSOR); - break; - } - } while (true); - } else if(menu->actions.enter && selected_favorite != -1) { - menu->load.load_favorite = selected_favorite; - - if(path_has_value(menu->history.favorites_disk[selected_favorite])) { + if(item_list[selected_item].bookkeeping_type == HISTORY_TYPE_DISK) { menu->next_mode = MENU_MODE_LOAD_DISK; sound_play_effect(SFX_ENTER); - } else if(path_has_value(menu->history.favorites_rom[selected_favorite])) { + } else if(item_list[selected_item].bookkeeping_type == HISTORY_TYPE_ROM) { menu->next_mode = MENU_MODE_LOAD_ROM; sound_play_effect(SFX_ENTER); } - } else if(menu->actions.options && selected_favorite != -1) { - history_favorite_remove(&menu->history, selected_favorite); - favorite_reset_selected(menu); + } else if (menu->actions.previous_tab) { + if(screen_mode == BOOKKEEPING_SCREEN_MODE_FAVORITE) { + menu->next_mode = MENU_MODE_HISTORY; + } else if(screen_mode == BOOKKEEPING_SCREEN_MODE_HISTORY) { + menu->next_mode = MENU_MODE_BROWSER; + } + } else if (menu->actions.next_tab) { + if(screen_mode == BOOKKEEPING_SCREEN_MODE_FAVORITE) { + menu->next_mode = MENU_MODE_BROWSER; + } else if(screen_mode == BOOKKEEPING_SCREEN_MODE_HISTORY) { + menu->next_mode = MENU_MODE_FAVORITE; + } + }else if(screen_mode == BOOKKEEPING_SCREEN_MODE_FAVORITE && menu->actions.options && selected_item != -1) { + //history_favorite_remove(&menu->history, selected_item); + reset_selected(menu); sound_play_effect(SFX_SETTING); } } static void draw_favorites(menu_t *menu, surface_t *display) { - float y = 24; - float x = 10; + float y = VISIBLE_AREA_Y0; + float x = 10 + VISIBLE_AREA_X0; - if(selected_favorite != -1) { - float highlight_y = 32 + y + (selected_favorite * 16 * 2); + if(selected_item != -1) { + float highlight_y = y + (selected_item * 18 * 2); ui_components_box_draw( VISIBLE_AREA_X0, highlight_y, VISIBLE_AREA_X0 + FILE_LIST_HIGHLIGHT_WIDTH, - highlight_y + 32, + highlight_y + 36, FILE_LIST_HIGHLIGHT_COLOR ); } - for(int i=0;i < FAVORITES_COUNT; i++) - { - ui_components_main_text_draw_location(x, y, "%d :", (i+1)); - if(path_has_value(menu->history.favorites_rom[i])) { - ui_components_main_text_draw_location(x + 64, y, "%s", path_last_get(menu->history.favorites_rom[i])); + for(int i=0;i < FAVORITES_COUNT; i++) { + if(path_has_value(item_list[i].primary_path)) { + ui_components_main_text_draw_location(x, y, "%d : %s",(i+1), path_last_get(item_list[i].primary_path)); + } else { + ui_components_main_text_draw_location(x, y, "%d :", (i+1)); } y += 16; - if(path_has_value(menu->history.favorites_disk[i])) { - ui_components_main_text_draw_location(x + 64, y,"%s", path_last_get(menu->history.favorites_disk[i])); + if(path_has_value(item_list[i].secondary_path)) { + ui_components_main_text_draw_location(x, y," %s", path_last_get(item_list[i].secondary_path)); } y += 20; } + + if(screen_mode == BOOKKEEPING_SCREEN_MODE_FAVORITE) { + ui_compontents_tabs_common_draw(2); + } else if(screen_mode == BOOKKEEPING_SCREEN_MODE_HISTORY) { + ui_compontents_tabs_common_draw(1); + } } static void draw(menu_t *menu, surface_t *display) { @@ -107,32 +147,22 @@ static void draw(menu_t *menu, surface_t *display) { ui_components_layout_draw(); - ui_components_main_text_draw( - ALIGN_CENTER, VALIGN_TOP, - "Favorites"); - draw_favorites(menu, display); - if(selected_favorite != -1) { + if(selected_item != -1) { ui_components_actions_bar_text_draw( ALIGN_LEFT, VALIGN_TOP, - "A: Load Favorite\n" - "B: Exit" - ); - - ui_components_actions_bar_text_draw( - ALIGN_RIGHT, VALIGN_TOP, - "R: Remove Favorite" - ); - } else { - ui_components_actions_bar_text_draw( - ALIGN_LEFT, VALIGN_TOP, - "\n" - "B: Exit" + "A: Load Game" ); + + if(screen_mode == BOOKKEEPING_SCREEN_MODE_FAVORITE) { + ui_components_actions_bar_text_draw( + ALIGN_RIGHT, VALIGN_TOP, + "R: Remove Favorite" + ); + } } - rdpq_detach_show(); } @@ -140,10 +170,29 @@ static void draw(menu_t *menu, surface_t *display) { void view_favorite_init (menu_t *menu) { - favorite_reset_selected(menu); + screen_mode = BOOKKEEPING_SCREEN_MODE_FAVORITE; + item_list = menu->history.favorite_items; + item_max = FAVORITES_COUNT; + + reset_selected(menu); } void view_favorite_display (menu_t *menu, surface_t *display) { process(menu); draw(menu, display); +} + + + +void view_history_init (menu_t *menu) { + screen_mode = BOOKKEEPING_SCREEN_MODE_HISTORY; + item_list = menu->history.history_items; + item_max = HISTORY_COUNT; + + reset_selected(menu); +} + +void view_history_display (menu_t *menu, surface_t *display) { + process(menu); + draw(menu, display); } \ No newline at end of file diff --git a/src/menu/views/load_disk.c b/src/menu/views/load_disk.c index 9262447a..20d89477 100644 --- a/src/menu/views/load_disk.c +++ b/src/menu/views/load_disk.c @@ -40,9 +40,6 @@ static void process (menu_t *menu) { } else if (menu->actions.back) { sound_play_effect(SFX_EXIT); menu->next_mode = MENU_MODE_BROWSER; - } else if (menu->actions.favorite) { - history_favorite_add(&menu->history, menu->load.rom_path, menu->load.disk_path); - sound_play_effect(SFX_SETTING); } } @@ -142,7 +139,7 @@ static void load (menu_t *menu) { return; } - history_last_rom_set(&menu->history, menu->load.disk_path, menu->load.rom_path); + bookkeeping_history_add(&menu->history, menu->load.disk_path, menu->load.rom_path, HISTORY_TYPE_DISK); menu->next_mode = MENU_MODE_BOOT; if (load_disk_with_rom) { @@ -196,24 +193,29 @@ void view_load_disk_init (menu_t *menu) { menu->boot_pending.disk_file = false; - if(menu->load.load_last) { - menu->load.disk_path = path_clone(menu->history.last_disk); + if(menu->load.load_history != -1 || menu->load.load_favorite != -1) { + int id = -1; + bookkeeping_item_t* items; - if(!load_rom(menu, menu->history.last_rom)) { + if(menu->load.load_history != -1) { + id = menu->load.load_history; + items = menu->history.history_items; + } else if (menu->load.load_favorite != -1) { + id = menu->load.load_favorite; + items = menu->history.favorite_items; + } + + menu->load.disk_path = path_clone(items[id].primary_path); + if(!load_rom(menu, items[id].secondary_path)) { return; } - } else if(menu->load.load_favorite != -1) { - menu->load.disk_path = path_clone(menu->history.favorites_disk[menu->load.load_favorite]); - if(!load_rom(menu, menu->history.favorites_rom[menu->load.load_favorite])) { - return; - } } else { menu->load.disk_path = path_clone_push(menu->browser.directory, menu->browser.entry->name); } menu->load.load_favorite = -1; - menu->load.load_last = false; + menu->load.load_history = -1; name = path_last_get(menu->load.disk_path); disk_err_t err = disk_info_load(menu->load.disk_path, &menu->load.disk_info); diff --git a/src/menu/views/load_rom.c b/src/menu/views/load_rom.c index 123f31af..2239dd9d 100644 --- a/src/menu/views/load_rom.c +++ b/src/menu/views/load_rom.c @@ -159,7 +159,7 @@ static void set_autoload_type (menu_t *menu, void *arg) { } static void add_favorite (menu_t *menu, void *arg) { - history_favorite_add(&menu->history, menu->load.rom_path, NULL); + bookkeeping_favorite_add(&menu->history, menu->load.rom_path, NULL, HISTORY_TYPE_ROM); } static component_context_menu_t set_cic_type_context_menu = { .list = { @@ -341,7 +341,7 @@ static void load (menu_t *menu) { return; } - history_last_rom_set(&menu->history, NULL, menu->load.rom_path); + bookkeeping_history_add(&menu->history, menu->load.rom_path, NULL, HISTORY_TYPE_ROM); menu->next_mode = MENU_MODE_BOOT; @@ -368,10 +368,10 @@ void view_load_rom_init (menu_t *menu) { path_free(menu->load.rom_path); } - if(menu->load.load_last) { - menu->load.rom_path = path_clone(menu->history.last_rom); + if(menu->load.load_history != -1) { + menu->load.rom_path = path_clone(menu->history.history_items[menu->load.load_history].primary_path); } else if(menu->load.load_favorite != -1) { - menu->load.rom_path = path_clone(menu->history.favorites_rom[menu->load.load_favorite]); + menu->load.rom_path = path_clone(menu->history.favorite_items[menu->load.load_history].primary_path); } else { menu->load.rom_path = path_clone_push(menu->browser.directory, menu->browser.entry->name); } @@ -380,7 +380,7 @@ void view_load_rom_init (menu_t *menu) { } menu->load.load_favorite = -1; - menu->load.load_last = false; + menu->load.load_history = -1; rom_err_t err = rom_info_load(menu->load.rom_path, &menu->load.rom_info); if (err != ROM_OK) { diff --git a/src/menu/views/views.h b/src/menu/views/views.h index df87762f..d088f8b2 100644 --- a/src/menu/views/views.h +++ b/src/menu/views/views.h @@ -68,7 +68,10 @@ void view_fault_display (menu_t *menu, surface_t *display); void view_favorite_init (menu_t *menu); void view_favorite_display (menu_t *menu, surface_t *display); +void view_history_init (menu_t *menu); + void menu_show_error (menu_t *menu, char *error_message); +void view_history_display (menu_t *menu, surface_t *display); /** @} */ /* view */