diff --git a/Package/Environment/Common/collections/_common/medium_artwork/playlist/favorites.png b/Package/Environment/Common/collections/_common/medium_artwork/playlist/favorites.png new file mode 100644 index 0000000..c400b02 Binary files /dev/null and b/Package/Environment/Common/collections/_common/medium_artwork/playlist/favorites.png differ diff --git a/Package/Environment/Common/layouts/Aeon Nox/layout 16x9.xml b/Package/Environment/Common/layouts/Aeon Nox/layout 16x9.xml index 1d49ea4..1eed0da 100644 --- a/Package/Environment/Common/layouts/Aeon Nox/layout 16x9.xml +++ b/Package/Environment/Common/layouts/Aeon Nox/layout 16x9.xml @@ -1970,4 +1970,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Package/Environment/Common/layouts/Aeon Nox/layout 4x3.xml b/Package/Environment/Common/layouts/Aeon Nox/layout 4x3.xml index 2bfc3eb..2098925 100644 --- a/Package/Environment/Common/layouts/Aeon Nox/layout 4x3.xml +++ b/Package/Environment/Common/layouts/Aeon Nox/layout 4x3.xml @@ -1970,4 +1970,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Package/Environment/Common/layouts/Aeon Nox/layout.xml b/Package/Environment/Common/layouts/Aeon Nox/layout.xml index 1d49ea4..1eed0da 100644 --- a/Package/Environment/Common/layouts/Aeon Nox/layout.xml +++ b/Package/Environment/Common/layouts/Aeon Nox/layout.xml @@ -1970,4 +1970,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/RetroFE/Source/Collection/CollectionInfo.cpp b/RetroFE/Source/Collection/CollectionInfo.cpp index 9071728..ffd25cc 100644 --- a/RetroFE/Source/Collection/CollectionInfo.cpp +++ b/RetroFE/Source/Collection/CollectionInfo.cpp @@ -51,16 +51,6 @@ CollectionInfo::CollectionInfo(std::string name, CollectionInfo::~CollectionInfo() { - // remove items from the subcollections so their destructors do not - // delete the items since the parent collection will delete them. - std::vector::iterator subit; - for (subit = subcollections_.begin(); subit != subcollections_.end(); subit++) - { - CollectionInfo *info = *subit; - info->items.clear(); - } - - Playlists_T::iterator pit = playlists.begin(); while(pit != playlists.end()) @@ -129,7 +119,14 @@ bool CollectionInfo::Save() std::vector *saveitems = playlists["favorites"]; for(std::vector::iterator it = saveitems->begin(); it != saveitems->end(); it++) { - filestream << (*it)->name << std::endl; + if ((*it)->collectionInfo->name == name) + { + filestream << (*it)->name << std::endl; + } + else + { + filestream << "_" << (*it)->collectionInfo->name << ":" << (*it)->name << std::endl; + } } filestream.close(); @@ -163,16 +160,9 @@ void CollectionInfo::extensionList(std::vector &extensionlist) void CollectionInfo::addSubcollection(CollectionInfo *newinfo) { - subcollections_.push_back(newinfo); - items.insert(items.begin(), newinfo->items.begin(), newinfo->items.end()); } -bool CollectionInfo::hasSubcollections() -{ - return (subcollections_.size() > 0); -} - bool CollectionInfo::itemIsLess(Item *lhs, Item *rhs) { if(lhs->leaf && !rhs->leaf) return true; @@ -189,3 +179,28 @@ void CollectionInfo::sortItems() std::sort(it->second->begin(), it->second->end(), itemIsLess); } } + + +void CollectionInfo::sortFavoriteItems() +{ + + std::vector *allItems = playlists["all"]; + std::vector favItems; + for(std::vector ::iterator itFav = playlists["favorites"]->begin(); itFav != playlists["favorites"]->end(); itFav++) + { + favItems.push_back((*itFav)); + } + playlists["favorites"]->clear(); + + + for(std::vector ::iterator itAll = allItems->begin(); itAll != allItems->end(); itAll++) + { + for(std::vector ::iterator itFav = favItems.begin(); itFav != favItems.end(); itFav++) + { + if ((*itAll) == (*itFav)) + { + playlists["favorites"]->push_back((*itAll)); + } + } + } +} diff --git a/RetroFE/Source/Collection/CollectionInfo.h b/RetroFE/Source/Collection/CollectionInfo.h index dd15d1a..ff26119 100644 --- a/RetroFE/Source/Collection/CollectionInfo.h +++ b/RetroFE/Source/Collection/CollectionInfo.h @@ -29,8 +29,8 @@ public: std::string settingsPath() const; bool Save(); void sortItems(); + void sortFavoriteItems(); void addSubcollection(CollectionInfo *info); - bool hasSubcollections(); void extensionList(std::vector &extensions); std::string name; std::string listpath; @@ -44,7 +44,6 @@ public: bool menusort; private: - std::vector subcollections_; std::string metadataPath_; std::string extensions_; static bool itemIsLess(Item *lhs, Item *rhs); diff --git a/RetroFE/Source/Collection/CollectionInfoBuilder.cpp b/RetroFE/Source/Collection/CollectionInfoBuilder.cpp index 4e7469a..9e86d31 100644 --- a/RetroFE/Source/Collection/CollectionInfoBuilder.cpp +++ b/RetroFE/Source/Collection/CollectionInfoBuilder.cpp @@ -232,12 +232,9 @@ bool CollectionInfoBuilder::ImportDirectory(CollectionInfo *info, std::string me DIR *dp; struct dirent *dirp; std::string path = info->listpath; - std::map allMap; std::map includeFilter; - std::map favoritesFilter; std::map excludeFilter; std::string includeFile = Utils::combinePath(Configuration::absolutePath, "collections", info->name, "include.txt"); - std::string favoritesFile = Utils::combinePath(Configuration::absolutePath, "collections", info->name, "playlists/favorites.txt"); std::string excludeFile = Utils::combinePath(Configuration::absolutePath, "collections", info->name, "exclude.txt"); std::string launcher; @@ -344,28 +341,52 @@ bool CollectionInfoBuilder::ImportDirectory(CollectionInfo *info, std::string me excludeFilter.erase(it); } - for(std::vector::iterator it = info->items.begin(); it != info->items.end(); it++) { - allMap[(*it)->fullTitle] = *it; - } - - - ImportBasicList(info, favoritesFile, favoritesFilter); info->playlists["all"] = &info->items; + return true; +} + + +void CollectionInfoBuilder::addFavorites(CollectionInfo *info) +{ + std::map favoritesFilter; + std::string favoritesFile = Utils::combinePath(Configuration::absolutePath, "collections", info->name, "playlists/favorites.txt"); + ImportBasicList(info, favoritesFile, favoritesFilter); + info->playlists["favorites"] = new std::vector(); // add the favorites list for(std::map::iterator it = favoritesFilter.begin(); it != favoritesFilter.end(); it++) { - std::map::iterator itemit = allMap.find(it->first); - - if(itemit != allMap.end()) + std::string collectionName = info->name; + std::string itemName = it->first; + if (itemName.at(0) == '_') // name consists of _: { - info->playlists["favorites"]->push_back(itemit->second); + itemName.erase(0, 1); // Remove _ + size_t position = itemName.find(":"); + if (position != std::string::npos ) + { + collectionName = itemName.substr(0, position); + itemName = itemName.erase(0, position+1); + } + } + + for(std::vector::iterator it = info->items.begin(); it != info->items.end(); it++) + { + if( (*it)->name == itemName && (*it)->collectionInfo->name == collectionName) + { + info->playlists["favorites"]->push_back((*it)); + } } } - - metaDB_.injectMetadata(info); - - return true; + return; +} + + + + +void CollectionInfoBuilder::injectMetadata(CollectionInfo *info) +{ + metaDB_.injectMetadata(info); + return; } diff --git a/RetroFE/Source/Collection/CollectionInfoBuilder.h b/RetroFE/Source/Collection/CollectionInfoBuilder.h index 250f384..cad87f5 100644 --- a/RetroFE/Source/Collection/CollectionInfoBuilder.h +++ b/RetroFE/Source/Collection/CollectionInfoBuilder.h @@ -31,6 +31,8 @@ public: virtual ~CollectionInfoBuilder(); CollectionInfo *buildCollection(std::string collectionName); CollectionInfo *buildCollection(std::string collectionName, std::string mergedCollectionName); + void addFavorites(CollectionInfo *info); + void injectMetadata(CollectionInfo *info); static bool createCollectionDirectory(std::string collectionName); private: diff --git a/RetroFE/Source/Graphics/Component/ReloadableMedia.cpp b/RetroFE/Source/Graphics/Component/ReloadableMedia.cpp index dd47f4c..45443b9 100644 --- a/RetroFE/Source/Graphics/Component/ReloadableMedia.cpp +++ b/RetroFE/Source/Graphics/Component/ReloadableMedia.cpp @@ -276,6 +276,10 @@ void ReloadableMedia::reloadTexture() { basename = selectedItem->score; } + else if(typeLC == "playlist") + { + basename = page.getPlaylistName(); + } Utils::replaceSlashesWithUnderscores(basename); diff --git a/RetroFE/Source/Graphics/Page.cpp b/RetroFE/Source/Graphics/Page.cpp index 620c32d..d0ea5eb 100644 --- a/RetroFE/Source/Graphics/Page.cpp +++ b/RetroFE/Source/Graphics/Page.cpp @@ -700,7 +700,6 @@ void Page::draw() void Page::removePlaylist() { if(!selectedItem_) return; - if(!selectedItem_->leaf) return; MenuInfo_S &info = collections_.back(); CollectionInfo *collection = info.collection; @@ -711,14 +710,15 @@ void Page::removePlaylist() if(it != items->end()) { items->erase(it); + collection->sortFavoriteItems(); collection->saveRequest = true; } + collection->Save(); } void Page::addPlaylist() { if(!selectedItem_) return; - if(!selectedItem_->leaf) return; MenuInfo_S &info = collections_.back(); CollectionInfo *collection = info.collection; @@ -727,9 +727,10 @@ void Page::addPlaylist() if(playlist_->first != "favorites" && std::find(items->begin(), items->end(), selectedItem_) == items->end()) { items->push_back(selectedItem_); - collection->sortItems(); + collection->sortFavoriteItems(); collection->saveRequest = true; } + collection->Save(); } std::string Page::getCollectionName() diff --git a/RetroFE/Source/RetroFE.cpp b/RetroFE/Source/RetroFE.cpp index 351d249..99808b8 100644 --- a/RetroFE/Source/RetroFE.cpp +++ b/RetroFE/Source/RetroFE.cpp @@ -321,17 +321,21 @@ void RetroFE::run() if(currentPage_) { std::string firstCollection = "Main"; - bool menuSort = true; config_.getProperty("firstCollection", firstCollection); - config_.getProperty("collections." + firstCollection + ".list.menuSort", menuSort); config_.setProperty("currentCollection", firstCollection); CollectionInfo *info = getCollection(firstCollection); - MenuParser mp; - - mp.buildMenuItems(info, menuSort); currentPage_->pushCollection(info); + + bool autoFavorites = true; + config_.getProperty("autoFavorites", autoFavorites); + + if (autoFavorites) + { + currentPage_->selectPlaylist("favorites"); // Switch to favorites playlist + } + currentPage_->onNewItemSelected(); currentPage_->reallocateMenuSpritePoints(); @@ -344,6 +348,36 @@ void RetroFE::run() } break; + case RETROFE_PLAYLIST_REQUEST: + currentPage_->highlightExit(); + currentPage_->setScrolling(Page::ScrollDirectionIdle); + state = RETROFE_PLAYLIST_EXIT; + break; + + case RETROFE_PLAYLIST_EXIT: + if (currentPage_->isIdle()) + { + currentPage_->onNewItemSelected(); + state = RETROFE_PLAYLIST_LOAD_ART; + } + break; + + case RETROFE_PLAYLIST_LOAD_ART: + if (currentPage_->isIdle()) + { + currentPage_->reallocateMenuSpritePoints(); + currentPage_->highlightEnter(); + state = RETROFE_PLAYLIST_ENTER; + } + break; + + case RETROFE_PLAYLIST_ENTER: + if (currentPage_->isIdle()) + { + state = RETROFE_IDLE; + } + break; + case RETROFE_HIGHLIGHT_REQUEST: currentPage_->highlightExit(); currentPage_->setScrolling(Page::ScrollDirectionIdle); @@ -395,6 +429,8 @@ void RetroFE::run() case RETROFE_NEXT_PAGE_MENU_EXIT: if(currentPage_->isIdle()) { + lastMenuOffsets_[currentPage_->getCollectionName()] = currentPage_->getScrollOffsetIndex(); + lastMenuPlaylists_[currentPage_->getCollectionName()] = currentPage_->getPlaylistName(); // Load new layout if available std::string layoutName; config_.getProperty("layout", layoutName); @@ -408,14 +444,10 @@ void RetroFE::run() currentPage_ = page; } - bool menuSort = true; config_.setProperty("currentCollection", nextPageName); - config_.getProperty("collections." + nextPageName + ".list.menuSort", menuSort); CollectionInfo *info = getCollection(nextPageName); - MenuParser mp; - mp.buildMenuItems(info, menuSort); currentPage_->pushCollection(info); bool rememberMenu = false; @@ -502,6 +534,26 @@ void RetroFE::run() currentPage_->popCollection(); } config_.setProperty("currentCollection", currentPage_->getCollectionName()); + + bool rememberMenu = false; + config_.getProperty("rememberMenu", rememberMenu); + bool autoFavorites = true; + config_.getProperty("autoFavorites", autoFavorites); + + if (rememberMenu && lastMenuPlaylists_.find(currentPage_->getCollectionName()) != lastMenuPlaylists_.end()) + { + currentPage_->selectPlaylist(lastMenuPlaylists_[currentPage_->getCollectionName()]); // Switch to last playlist + } + else if (autoFavorites) + { + currentPage_->selectPlaylist("favorites"); // Switch to favorites playlist + } + + if(rememberMenu && lastMenuOffsets_.find(currentPage_->getCollectionName()) != lastMenuOffsets_.end()) + { + currentPage_->setScrollOffsetIndex(lastMenuOffsets_[currentPage_->getCollectionName()]); + } + currentPage_->onNewItemSelected(); currentPage_->reallocateMenuSpritePoints(); state = RETROFE_BACK_MENU_LOAD_ART; @@ -671,19 +723,17 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput(Page *page) if(input_.newKeyPressed(UserInput::KeyCodeNextPlaylist)) { page->nextPlaylist(); - page->reallocateMenuSpritePoints(); - state = RETROFE_HIGHLIGHT_REQUEST; + state = RETROFE_PLAYLIST_REQUEST; } if(input_.newKeyPressed(UserInput::KeyCodeRemovePlaylist)) { page->removePlaylist(); - page->onNewItemSelected(); - page->reallocateMenuSpritePoints(); + state = RETROFE_PLAYLIST_REQUEST; } if(input_.newKeyPressed(UserInput::KeyCodeAddPlaylist)) { page->addPlaylist(); - page->reallocateMenuSpritePoints(); + state = RETROFE_PLAYLIST_REQUEST; } if(input_.keystate(UserInput::KeyCodeRandom)) { @@ -779,6 +829,8 @@ CollectionInfo *RetroFE::getCollection(std::string collectionName) CollectionInfoBuilder cib(config_, *metadb_); CollectionInfo *collection = cib.buildCollection(collectionName); + cib.injectMetadata(collection); + DIR *dp; struct dirent *dirp; @@ -803,11 +855,21 @@ CollectionInfo *RetroFE::getCollection(std::string collectionName) CollectionInfo *subcollection = cib.buildCollection(basename, collectionName); collection->addSubcollection(subcollection); + cib.injectMetadata(subcollection); } } } collection->sortItems(); + + bool menuSort = true; + config_.getProperty("collections." + collectionName + ".list.menuSort", menuSort); + MenuParser mp; + mp.buildMenuItems(collection, menuSort); + + cib.addFavorites(collection); + collection->sortFavoriteItems(); + return collection; } diff --git a/RetroFE/Source/RetroFE.h b/RetroFE/Source/RetroFE.h index b0c9a1d..620f073 100644 --- a/RetroFE/Source/RetroFE.h +++ b/RetroFE/Source/RetroFE.h @@ -55,6 +55,10 @@ private: RETROFE_LOAD_ART, RETROFE_ENTER, RETROFE_SPLASH_EXIT, + RETROFE_PLAYLIST_REQUEST, + RETROFE_PLAYLIST_EXIT, + RETROFE_PLAYLIST_LOAD_ART, + RETROFE_PLAYLIST_ENTER, RETROFE_HIGHLIGHT_REQUEST, RETROFE_HIGHLIGHT_EXIT, RETROFE_HIGHLIGHT_LOAD_ART, diff --git a/RetroFE/Source/Version.cpp b/RetroFE/Source/Version.cpp index b35b9ff..a0269fa 100644 --- a/RetroFE/Source/Version.cpp +++ b/RetroFE/Source/Version.cpp @@ -20,7 +20,7 @@ std::string retrofe_version_major = "0"; std::string retrofe_version_minor = "7"; -std::string retrofe_version_build = "15"; +std::string retrofe_version_build = "16"; std::string Version::getString()