From b0872d2374d9e0cc5a89749764c3010b2650bbf9 Mon Sep 17 00:00:00 2001 From: Vincent-FK Date: Sun, 22 Mar 2020 17:43:24 +0100 Subject: [PATCH] add theme chooser in menu Signed-off-by: Vincent-FK --- RetroFE/Source/Database/Configuration.cpp | 102 ++++++++++++++++++++++ RetroFE/Source/Database/Configuration.h | 7 +- RetroFE/Source/Main.cpp | 16 ++-- RetroFE/Source/Menu/MenuMode.cpp | 93 +++++++++++++++++--- RetroFE/Source/Menu/MenuMode.h | 11 ++- RetroFE/Source/RetroFE.cpp | 22 +++-- 6 files changed, 219 insertions(+), 32 deletions(-) diff --git a/RetroFE/Source/Database/Configuration.cpp b/RetroFE/Source/Database/Configuration.cpp index dfafab7..9bd6885 100644 --- a/RetroFE/Source/Database/Configuration.cpp +++ b/RetroFE/Source/Database/Configuration.cpp @@ -193,6 +193,108 @@ bool Configuration::importLayouts(std::string folder, std::string file, bool mus } +bool Configuration::importCurrentLayout(std::string folder, std::string file, bool mustExist) +{ + bool retVal = false; + int lineCount = 0; + std::string line; + int index = 0; + + Logger::write(Logger::ZONE_INFO, "Configuration", "Importing layouts from \"" + file + "\""); + + std::ifstream ifs(file.c_str()); + + if (!ifs.is_open()) + { + if (mustExist) + { + Logger::write(Logger::ZONE_ERROR, "Configuration", "Could not open " + file + "\""); + } + else + { + Logger::write(Logger::ZONE_INFO, "Configuration", "Could not open " + file + "\""); + } + + return false; + } + + while (std::getline (ifs, line)) + { + lineCount++; + + // strip out any comments + line = Utils::filterComments(line); + + // line empty + if(line.empty() || (line.find_first_not_of(" \t\r") == std::string::npos)) + { + retVal = false; + } + // finding layout in existing list + else + { + std::string seekedLayoutName = trimEnds(line); + std::string layoutPathFound; + bool layoutFoundInList = false; + + // check existing layout list */ + for(std::vector::iterator it = layouts_.begin(); it != layouts_.end(); ++it){ + std::string curLayoutName = Utils::getFileName(*it); + if(!curLayoutName.compare(seekedLayoutName)){ + layoutPathFound = *it; + layoutFoundInList = true; + break; + } + index++; + } + + if (layoutFoundInList){ + + /* remove layout properties if they already exist */ + if(properties_.find("layout") != properties_.end()) + { + properties_.erase("layout"); + } + + /* Set new pair for key = layout */ + properties_.insert(PropertiesPair("layout", seekedLayoutName)); + + std::stringstream ss; + //printf("Found layout: %s at idx %d\n", layoutPathFound.c_str(), index); + ss << "Found layout: " << "\"" << layoutPathFound << "\" in layouts list at idx " << index; + Logger::write(Logger::ZONE_INFO, "Configuration", ss.str()); + retVal = true; + + break; + } + else{ + } + } + } + + ifs.close(); + + currentLayoutIdx_ = index; + + return retVal; +} + +bool Configuration::exportCurrentLayout(std::string layoutFilePath, std::string layoutName) +{ + bool retVal = false; + + Logger::write(Logger::ZONE_INFO, "Configuration", "Exporting layout \"" + layoutName + + "\" in file \"" + layoutFilePath +"\""); + + std::ofstream layoutFile; + layoutFile.open(layoutFilePath.c_str()); + layoutFile << layoutName << std::endl; + layoutFile.close(); + + return retVal; +} + + bool Configuration::parseLine(std::string collection, std::string keyPrefix, std::string line, int lineCount) { bool retVal = false; diff --git a/RetroFE/Source/Database/Configuration.h b/RetroFE/Source/Database/Configuration.h index 01d655b..d432da2 100644 --- a/RetroFE/Source/Database/Configuration.h +++ b/RetroFE/Source/Database/Configuration.h @@ -31,6 +31,8 @@ public: bool import(std::string keyPrefix, std::string file); bool import(std::string collection, std::string keyPrefix, std::string file, bool mustExist = true); bool importLayouts(std::string folder, std::string file, bool mustExist = true); + bool importCurrentLayout(std::string folder, std::string file, bool mustExist = true); + bool exportCurrentLayout(std::string layoutFilePath, std::string layoutName); bool getProperty(std::string key, std::string &value); bool getProperty(std::string key, int &value); bool getProperty(std::string key, bool &value); @@ -42,8 +44,9 @@ public: void getMediaPropertyAbsolutePath(std::string collectionName, std::string mediaType, std::string &value); void getMediaPropertyAbsolutePath(std::string collectionName, std::string mediaType, bool system, std::string &value); void getCollectionAbsolutePath(std::string collectionName, std::string &value); - static std::string absolutePath; - std::vector layouts_; + static std::string absolutePath; + std::vector layouts_; + int currentLayoutIdx_; private: bool getRawProperty(std::string key, std::string &value); diff --git a/RetroFE/Source/Main.cpp b/RetroFE/Source/Main.cpp index 347c23d..8a1184c 100644 --- a/RetroFE/Source/Main.cpp +++ b/RetroFE/Source/Main.cpp @@ -129,15 +129,8 @@ bool ImportConfiguration(Configuration *c) Logger::write(Logger::ZONE_ERROR, "RetroFE", "Could not import \"" + settingsConfPath + "\""); return false; } - - /* Read current layout */ - std::string layoutConfPath = Utils::combinePath(configPath, "layout.conf"); - if(!c->import("", layoutConfPath)) - { - Logger::write(Logger::ZONE_ERROR, "RetroFE", "Could not import \"" + layoutConfPath + "\""); - } - /* Read layouts */ + /* Read layouts in absolute path */ std::string layoutDefaultPath = Utils::combinePath(Configuration::absolutePath, "layouts"); std::string layoutListDefaultPath = Utils::combinePath(layoutDefaultPath, "layouts.list"); if(!c->importLayouts(layoutDefaultPath, layoutListDefaultPath)) @@ -153,6 +146,13 @@ bool ImportConfiguration(Configuration *c) Logger::write(Logger::ZONE_ERROR, "RetroFE", "Could not import \"" + layoutListUserPath + "\""); } + /* Read current layout */ + std::string layoutConfPath = Utils::combinePath(configPath, "layout.conf"); + if(!c->importCurrentLayout(configPath, layoutConfPath)) + { + Logger::write(Logger::ZONE_ERROR, "RetroFE", "Could not set layout from file \"" + layoutConfPath + "\""); + } + /* Open Launchers folder */ dp = opendir(launchersPath.c_str()); if(dp == NULL) diff --git a/RetroFE/Source/Menu/MenuMode.cpp b/RetroFE/Source/Menu/MenuMode.cpp index fd37da9..e6b7dac 100644 --- a/RetroFE/Source/Menu/MenuMode.cpp +++ b/RetroFE/Source/Menu/MenuMode.cpp @@ -2,6 +2,7 @@ #include "../Utility/Utils.h" #include #include "../SDL.h" +#include "../Utility/Utils.h" /// -------------- DEFINES -------------- #define MIN(a,b) (((a)<(b))?(a):(b)) @@ -70,7 +71,6 @@ int *MenuMode::idx_menus = NULL; int MenuMode::nb_menu_zones = 0; int MenuMode::menuItem=0; int MenuMode::stop_menu_loop = 0; -std::vector MenuMode::layouts_; SDL_Color MenuMode::text_color = {GRAY_MAIN_R, GRAY_MAIN_G, GRAY_MAIN_B}; int MenuMode::padding_y_from_center_menu_zone = 18; @@ -91,7 +91,9 @@ int MenuMode::aspect_ratio = ASPECT_RATIOS_TYPE_STRECHED; int MenuMode::aspect_ratio_factor_percent = 50; int MenuMode::aspect_ratio_factor_step = 10; +Configuration *MenuMode::config = NULL; int MenuMode::savestate_slot = 0; +int MenuMode::indexChooseLayout = 0; /// USB stuff int usb_data_connected = 0; @@ -134,13 +136,8 @@ void MenuMode::init(Configuration &c) MENU_ERROR_PRINTF("ERROR IMG_Load: %s\n", IMG_GetError()); } - /// ------ Copy config's layouts ------ - layouts_ = c.layouts_; - - std::vector::iterator it; - for (it= layouts_.begin(); it < layouts_.end(); it++){ - printf("%s\n", (*it).c_str()); - } + /// ------ Save config pointer ------ + config = &c; /// ------ Init menu zones ------ init_menu_zones(); @@ -487,10 +484,13 @@ void MenuMode::menu_screen_refresh(int menuItem, int prevItem, int scroll, uint8 /// --------- No Scroll ? Blitting menu-specific info else{ SDL_Surface * text_surface = NULL; - char text_tmp[40]; + char text_tmp[100]; SDL_Rect text_pos; char fname[MAXPATHLEN]; memset(fname, 0, MAXPATHLEN); + char *curLayoutName; + bool dots=false; + int max_chars = 15; switch(idx_menus[menuItem]){ case MENU_TYPE_VOLUME: @@ -590,6 +590,38 @@ void MenuMode::menu_screen_refresh(int menuItem, int prevItem, int scroll, uint8 } break; + case MENU_TYPE_THEME: + /// ---- Write current chosen theme ----- + curLayoutName = (char*)Utils::getFileName(config->layouts_.at(indexChooseLayout)).c_str(); + + // no more than max_chars chars in name to fit screen + if(strlen(curLayoutName) > max_chars){ + curLayoutName[max_chars-2] = 0; + dots = true; + } + sprintf(text_tmp, "< %s%s >", curLayoutName, dots?"...":"" ); + + text_surface = TTF_RenderText_Blended(menu_info_font, text_tmp, text_color); + text_pos.x = (virtual_hw_screen->w - MENU_ZONE_WIDTH)/2 + (MENU_ZONE_WIDTH - text_surface->w)/2; + text_pos.y = virtual_hw_screen->h - MENU_ZONE_HEIGHT/2 - text_surface->h/2; + SDL_BlitSurface(text_surface, NULL, virtual_hw_screen, &text_pos); + + if(menu_action){ + sprintf(text_tmp, "In progress..."); + text_surface = TTF_RenderText_Blended(menu_info_font, text_tmp, text_color); + text_pos.x = (virtual_hw_screen->w - MENU_ZONE_WIDTH)/2 + (MENU_ZONE_WIDTH - text_surface->w)/2; + text_pos.y = virtual_hw_screen->h - MENU_ZONE_HEIGHT/2 - text_surface->h/2 + 2*padding_y_from_center_menu_zone; + SDL_BlitSurface(text_surface, NULL, virtual_hw_screen, &text_pos); + } + else if(menu_confirmation){ + sprintf(text_tmp, "Are you sure ?"); + text_surface = TTF_RenderText_Blended(menu_info_font, text_tmp, text_color); + text_pos.x = (virtual_hw_screen->w - MENU_ZONE_WIDTH)/2 + (MENU_ZONE_WIDTH - text_surface->w)/2; + text_pos.y = virtual_hw_screen->h - MENU_ZONE_HEIGHT/2 - text_surface->h/2 + 2*padding_y_from_center_menu_zone; + SDL_BlitSurface(text_surface, NULL, virtual_hw_screen, &text_pos); + } + break; + case MENU_TYPE_EXIT: case MENU_TYPE_POWERDOWN: if(menu_action){ @@ -640,7 +672,7 @@ void MenuMode::menu_screen_refresh(int menuItem, int prevItem, int scroll, uint8 } -void MenuMode::launch( ) +int MenuMode::launch( ) { MENU_DEBUG_PRINTF("Launch MenuMode\n"); @@ -655,6 +687,8 @@ void MenuMode::launch( ) uint8_t menu_confirmation = 0; stop_menu_loop = 0; char fname[MAXPATHLEN]; + indexChooseLayout = config->currentLayoutIdx_; + int returnCode = MENU_RETURN_OK; /// ------ Get init values ------- init_menu_system_values(); @@ -676,6 +710,7 @@ void MenuMode::launch( ) { case SDL_QUIT: stop_menu_loop = 1; + returnCode = MENU_RETURN_EXIT; break; case SDL_KEYDOWN: switch (event.key.keysym.sym) @@ -809,6 +844,12 @@ void MenuMode::launch( ) /// ------ Refresh screen ------ screen_refresh = 1; } + else if(idx_menus[menuItem] == MENU_TYPE_THEME){ + MENU_DEBUG_PRINTF("Theme previous\n"); + indexChooseLayout = (!indexChooseLayout)?(config->layouts_.size()-1):(indexChooseLayout-1); + /// ------ Refresh screen ------ + screen_refresh = 1; + } break; case SDLK_r: @@ -863,6 +904,12 @@ void MenuMode::launch( ) /// ------ Refresh screen ------ screen_refresh = 1; } + else if(idx_menus[menuItem] == MENU_TYPE_THEME){ + MENU_DEBUG_PRINTF("Theme previous\n"); + indexChooseLayout = (indexChooseLayout+1)%config->layouts_.size(); + /// ------ Refresh screen ------ + screen_refresh = 1; + } break; case SDLK_a: @@ -933,6 +980,26 @@ void MenuMode::launch( ) screen_refresh = 1; } } + else if(idx_menus[menuItem] == MENU_TYPE_THEME){ + if(menu_confirmation){ + MENU_DEBUG_PRINTF("Theme change - confirmed\n"); + + /// ------ Refresh Screen ------- + menu_screen_refresh(menuItem, prevItem, scroll, menu_confirmation, 1); + + /// ----- Write new theme and restart RetroFe ---- + config->exportCurrentLayout(Utils::combinePath(Configuration::absolutePath, "layout.conf"), + Utils::getFileName(config->layouts_.at(indexChooseLayout))); + stop_menu_loop = 1; + returnCode = MENU_RETURN_EXIT; + } + else{ + MENU_DEBUG_PRINTF("Theme change - asking confirmation\n"); + menu_confirmation = 1; + /// ------ Refresh screen ------ + screen_refresh = 1; + } + } else if(idx_menus[menuItem] == MENU_TYPE_EXIT){ MENU_DEBUG_PRINTF("Exit game\n"); if(menu_confirmation){ @@ -940,8 +1007,8 @@ void MenuMode::launch( ) /// ----- The game should be saved here ---- /// ----- Exit game and back to launcher ---- - //quit(); stop_menu_loop = 1; + returnCode = MENU_RETURN_EXIT; } else{ MENU_DEBUG_PRINTF("Exit game - asking confirmation\n"); @@ -963,6 +1030,8 @@ void MenuMode::launch( ) if (fp == NULL) { MENU_ERROR_PRINTF("Failed to run command %s\n", shell_cmd); } + + return MENU_RETURN_EXIT; } else{ MENU_DEBUG_PRINTF("Powerdown - asking confirmation\n"); @@ -1019,5 +1088,5 @@ void MenuMode::launch( ) if(SDL_EnableKeyRepeat(backup_key_repeat_delay, backup_key_repeat_interval)){ MENU_ERROR_PRINTF("ERROR with SDL_EnableKeyRepeat: %s\n", SDL_GetError()); } - return; + return returnCode; } diff --git a/RetroFE/Source/Menu/MenuMode.h b/RetroFE/Source/Menu/MenuMode.h index 7cf410a..1561a30 100644 --- a/RetroFE/Source/Menu/MenuMode.h +++ b/RetroFE/Source/Menu/MenuMode.h @@ -18,6 +18,12 @@ typedef enum{ NB_MENU_TYPES, } ENUM_MENU_TYPE; +typedef enum{ + MENU_RETURN_OK, + MENU_RETURN_EXIT, + NB_MENU_RETURN_CODES, +} ENUM_MENU_RETURN_CODES; + ///------ Definition of the different aspect ratios #define ASPECT_RATIOS \ @@ -52,7 +58,7 @@ public: //MenuMode(); static void init(Configuration &c); static void end(); - static void launch( ); + static int launch( ); /*static SDL_Surface * draw_screen; @@ -132,5 +138,6 @@ private: static int savestate_slot; - static std::vector layouts_; + static Configuration *config; + static int indexChooseLayout; }; diff --git a/RetroFE/Source/RetroFE.cpp b/RetroFE/Source/RetroFE.cpp index 48ce4b5..0d2644b 100644 --- a/RetroFE/Source/RetroFE.cpp +++ b/RetroFE/Source/RetroFE.cpp @@ -370,6 +370,7 @@ void RetroFE::run( ) std::string firstCollection = "Main"; bool running = true; bool initInBackground = false; + int res; config_.getProperty( "initInBackground", initInBackground ); RETROFE_STATE state = RETROFE_NEW; @@ -570,7 +571,7 @@ void RetroFE::run( ) config_.getProperty( "collectionInputClear", collectionInputClear ); if ( collectionInputClear ) { - // Empty event queue + // Empty event queue SDL_Event e; while ( SDL_PollEvent( &e ) ); input_.resetStates( ); @@ -921,16 +922,21 @@ void RetroFE::run( ) /// Launch menu menuMode_ = true; printf("Menu launched here\n"); - MenuMode::launch(); + res = MenuMode::launch(); menuMode_ = false; forceRender(true); - /// Clear events - SDL_Event ev; - while ( SDL_PollEvent( &ev ) ); - input_.resetStates( ); - state = RETROFE_IDLE; - break; + /// Clear events + SDL_Event ev; + while ( SDL_PollEvent( &ev ) ); + input_.resetStates( ); + if(res == MENU_RETURN_EXIT){ + state = RETROFE_QUIT_REQUEST; + } + else{ + state = RETROFE_IDLE; + } + break; case RETROFE_MENUMODE_START_LOAD_ART: //currentPage_->start();