From 6a67d1c0a9922bfec2593593151952a45425f2db Mon Sep 17 00:00:00 2001
From: Thomas Jentzsch
Date: Mon, 29 Nov 2021 09:27:41 +0100
Subject: [PATCH] add option for removing recent/popular files tried to fix the
Linux compile problem renamed the (internal) Settings keys used to store the
favorites further updated doc
---
docs/index.html | 94 +++++++++++++++++++++++-------
src/emucore/Settings.cxx | 6 +-
src/gui/FavoritesManager.cxx | 36 ++++++++----
src/gui/FavoritesManager.hxx | 4 +-
src/gui/LauncherDialog.cxx | 43 +++++++++-----
src/gui/LauncherFileListWidget.cxx | 37 ++++++------
src/gui/LauncherFileListWidget.hxx | 5 ++
7 files changed, 157 insertions(+), 68 deletions(-)
diff --git a/docs/index.html b/docs/index.html
index 805c130f5..64a15edcc 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -307,6 +307,7 @@
TIA sprites and collisions for each object separately
Full system state save/load functionality
Automatic save state creation ('Time Machine') which allows moving back and forth in the recorded timeline
+ Tracking of user favorites and popular or recently played ROMs.
High scores saving (internal or via PlusROM High Score Club)
Cross-platform UI including a built-in ROM launcher frontend
Built-in extensive debugger, including static analysis with the Distella disassembler
@@ -2263,6 +2264,16 @@
Backspace |
Backspace |
+
+ Remove from 'Recently Played' or 'Most Popular' folder |
+ Control + X |
+ Control + X |
+
+
+ Toggle favorite |
+ Control + F |
+ Control + F |
+
Open Power-On options dialog |
Control + P |
@@ -2274,20 +2285,25 @@
Control + H |
- Toggle favorite |
- Control + F |
- Control + F |
+ Toggle file extensions display |
+ Control + E |
+ Control + E |
+
+
+ Toggle show all ROMs |
+ Control + A |
+ Control + A |
+
+
+ Toggle search ROMs in subdirectories too |
+ Control + D |
+ Control + D |
Reload ROM listing |
Control + R |
Control + R |
-
- Toggle file extensions display |
- Control + X |
- Control + X |
-
UI Keys in Text Editing areas (cannot be remapped)
@@ -3250,6 +3266,16 @@
directory only or all subdirectories too.
+
+ -altsorting <1|0> |
+ Alternative sorting in virtual folders. |
+
+
+
+ -maxrecentroms <1|0> |
+ Number of ROMs tracked in 'Recently played' folder. |
+
+
-romviewer <float> |
Hide ROM Info Viewer in ROM launcher mode (0) or use the
@@ -4210,12 +4236,21 @@
- The ROM launcher also contains a context menu, selected by clicking the
- right mouse button in the ROM list. This context menu
- contains the following items:
+ The ROM launcher also contains a context menu, opened by clicking the
+ right mouse button in the ROM list or by a long controller button press.
+ This context menu can contain the following items:
-
- Power-on options: Selecting this option shows a dialog whereby
+
+ -
+
Remove from recently played/most popular (or 'Control + X'):
+ This option removes the selected ROM from the current folder.
+
+ -
+
Add to/remove from favorites (or 'Control + F'): This option
+ toggles the favorite state of the selected ROM.
+
+ Power-on options (or 'Control + P'):
+ Selecting this option shows a dialog whereby
ROM properties can be temporarily overridden, and joystick/console buttons can be
temporarily held down. Selecting options from this dialog will cause all ROMs launched
after that to use those properties you specify. Clicking Defaults will disable
@@ -4243,16 +4278,33 @@
|
- This dialog can also be opened by pressing 'Control + P'.
- High scores: This option displays the
- High Scores dialog for the selected ROM. Only available if high score
- properties have been setup for the ROM. Also available via 'Control + H' keys combo.
+
+ High scores (or 'Control + H'): This option displays the
+ High Scores dialog for the selected ROM. Only available if high score
+ properties have been setup for the ROM.
-
Reload listing: Selecting this performs a reload of the
- current listing. It is an alternative to pressing the 'Control + R'
- key combo.
-
+
+ Enable/disable file extensions (or 'Control + E'): Toggles the
+ display of the file extensions.
+
+
+ Toggle alternative sorting (or 'Control + S'): Toggles
+ alternative sorting in the virtual directories.
+
+
+ Show all files/only ROMs (or 'Control + A'): Toggles display of
+ non-ROM files.
+
+
+ Include/exclude subdirectories (or 'Control + D'): Toggles searching
+ of ROMs in current directory only or all subdirectories too.
+
+
+ Reload listing (or 'Control + R'): Selecting this performs a
+ reload of the current listing.
+
+
diff --git a/src/emucore/Settings.cxx b/src/emucore/Settings.cxx
index d3ee3583a..804502a00 100644
--- a/src/emucore/Settings.cxx
+++ b/src/emucore/Settings.cxx
@@ -157,10 +157,10 @@ Settings::Settings()
setPermanent("launcherextensions", "false");
setPermanent("romviewer", "1");
setPermanent("lastrom", "");
- setPermanent("favoriteroms", "");
- setPermanent("recentroms", "");
+ setPermanent("_favoriteroms", ""); // internal only
+ setPermanent("_recentroms", ""); // internal only
setPermanent("maxrecentroms", "20");
- setPermanent("popularroms", "");
+ setPermanent("_popularroms", ""); // internal only
setPermanent("altsorting", "false");
// UI-related options
diff --git a/src/gui/FavoritesManager.cxx b/src/gui/FavoritesManager.cxx
index 36ba57581..13ffe88c0 100644
--- a/src/gui/FavoritesManager.cxx
+++ b/src/gui/FavoritesManager.cxx
@@ -36,7 +36,7 @@ void FavoritesManager::load()
// User Favorites
myUserSet.clear();
- const string& serializedUser = mySettings.getString("favoriteroms");
+ const string& serializedUser = mySettings.getString("_favoriteroms");
if(!serializedUser.empty())
{
const json& jUser = json::parse(serializedUser);
@@ -49,7 +49,7 @@ void FavoritesManager::load()
// Recently Played
myRecentList.clear();
- const string& serializedRecent = mySettings.getString("recentroms");
+ const string& serializedRecent = mySettings.getString("_recentroms");
if(!serializedRecent.empty())
{
const json& jRecent = json::parse(serializedRecent);
@@ -62,7 +62,7 @@ void FavoritesManager::load()
// Most Popular
myPopularMap.clear();
- const string& serializedPopular = mySettings.getString("popularroms");
+ const string& serializedPopular = mySettings.getString("_popularroms");
if(!serializedPopular.empty())
{
const json& jPopular = json::parse(serializedPopular);
@@ -82,19 +82,19 @@ void FavoritesManager::save()
json jUser = json::array();
for(const auto& path : myUserSet)
jUser.push_back(path);
- mySettings.setValue("favoriteroms", jUser.dump(2));
+ mySettings.setValue("_favoriteroms", jUser.dump(2));
// Recently Played
json jRecent = json::array();
for(const auto& path : myRecentList)
jRecent.push_back(path);
- mySettings.setValue("recentroms", jRecent.dump(2));
+ mySettings.setValue("_recentroms", jRecent.dump(2));
// Most Popular
json jPopular = json::array();
for(const auto& path : myPopularMap)
- jPopular.push_back(path);
- mySettings.setValue("popularroms", jPopular.dump(2));
+ jPopular.emplace_back(path);
+ mySettings.setValue("_popularroms", jPopular.dump(2));
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -159,17 +159,25 @@ void FavoritesManager::update(const string& path)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FavoritesManager::addRecent(const string& path)
{
- auto it = std::find(myRecentList.begin(), myRecentList.end(), path);
-
// Always remove existing before adding at the end again
- if(it != myRecentList.end())
- myRecentList.erase(it);
+ removeRecent(path);
myRecentList.emplace_back(path);
+
// Limit size
while(myRecentList.size() > myMaxRecent)
myRecentList.erase(myRecentList.begin());
}
+bool FavoritesManager::removeRecent(const string& path)
+{
+ auto it = std::find(myRecentList.begin(), myRecentList.end(), path);
+
+ if(it != myRecentList.end())
+ myRecentList.erase(it);
+
+ return it != myRecentList.end();
+}
+
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const FavoritesManager::RecentList& FavoritesManager::recentList() const
{
@@ -198,6 +206,11 @@ const FavoritesManager::RecentList& FavoritesManager::recentList() const
return sortedList;
}
+bool FavoritesManager::removePopular(const string& path)
+{
+ return myPopularMap.erase(path);
+}
+
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FavoritesManager::incPopular(const string& path)
{
@@ -220,7 +233,6 @@ void FavoritesManager::incPopular(const string& path)
auto entry = myPopularMap.find(item->first);
if(entry != myPopularMap.end())
{
- //if(item - sortedList.cbegin() <= min_popular)
if(entry->second >= scale * (1.0 - factor))
entry->second *= factor; // age data
else
diff --git a/src/gui/FavoritesManager.hxx b/src/gui/FavoritesManager.hxx
index 13c020446..2658e032e 100644
--- a/src/gui/FavoritesManager.hxx
+++ b/src/gui/FavoritesManager.hxx
@@ -54,9 +54,11 @@ class FavoritesManager
void update(const string& path);
// Recently played
+ bool removeRecent(const string& path);
const RecentList& recentList() const;
// Most popular
+ bool removePopular(const string& path);
const PopularList& popularList() const;
@@ -67,7 +69,7 @@ class FavoritesManager
UserSet myUserSet;
RecentList myRecentList;
PopularMap myPopularMap;
- uInt32 myMaxRecent{10};
+ uInt32 myMaxRecent{20};
Settings& mySettings;
diff --git a/src/gui/LauncherDialog.cxx b/src/gui/LauncherDialog.cxx
index 7aacad097..4006c643c 100644
--- a/src/gui/LauncherDialog.cxx
+++ b/src/gui/LauncherDialog.cxx
@@ -630,6 +630,11 @@ void LauncherDialog::handleContextMenu()
if(cmd == "favorite")
myList->toggleUserFavorite();
+ else if(cmd == "remove")
+ {
+ myList->removeFavorite();
+ reload();
+ }
else if(cmd == "override")
openGlobalProps();
else if(cmd == "extensions")
@@ -640,12 +645,12 @@ void LauncherDialog::handleContextMenu()
toggleShowAll();
else if(cmd == "subdirs")
toggleSubDirs();
- else if(cmd == "reload")
- reload();
else if(cmd == "highscores")
openHighScores();
else if(cmd == "options")
openSettings();
+ else if(cmd == "reload")
+ reload();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -686,6 +691,10 @@ void LauncherDialog::handleKeyDown(StellaKey key, StellaMod mod, bool repeated)
toggleSubDirs();
break;
+ case KBDK_E:
+ toggleExtensions();
+ break;
+
case KBDK_F:
myList->toggleUserFavorite();
break;
@@ -712,7 +721,8 @@ void LauncherDialog::handleKeyDown(StellaKey key, StellaMod mod, bool repeated)
break;
case KBDK_X:
- toggleExtensions();
+ myList->removeFavorite();
+ reload();
break;
default:
@@ -1006,12 +1016,12 @@ void LauncherDialog::toggleSorting()
void LauncherDialog::addContextItem(VariantList& items, const string& label,
const string& shortcut, const string& key)
{
- const string pad = " ";
+ const string pad = " ";
if(myUseMinimalUI)
VarList::push_back(items, " " + label + " ", key);
else
- VarList::push_back(items, " " + label + pad.substr(0, 24 - label.length())
+ VarList::push_back(items, " " + label + pad.substr(0, 29 - label.length())
+ shortcut + " ", key);
}
@@ -1030,14 +1040,21 @@ void LauncherDialog::openContextMenu(int x, int y)
// TODO: remove subdirs and show all from GUI
- if(!currentNode().isDirectory() && Bankswitch::isValidRomName(currentNode()))
+ if(!currentNode().isDirectory())
{
- addContextItem(items, myList->isUserFavorite(myList->selected().getPath())
- ? "Remove from favorites"
- : "Add to favorites", "Ctrl+F", "favorite");
- addContextItem(items, "Power-on options" + ELLIPSIS, "Ctrl+P", "override");
- if(instance().highScores().enabled())
- addContextItem(items, "High scores" + ELLIPSIS, "Ctrl+H", "highscores");
+ if(myList->inRecentDir())
+ addContextItem(items, "Remove from recently played", "Ctrl+X", "remove");
+ if(myList->inPopularDir())
+ addContextItem(items, "Remove from most popular", "Ctrl+X", "remove");
+ if(Bankswitch::isValidRomName(currentNode()))
+ {
+ addContextItem(items, myList->isUserFavorite(myList->selected().getPath())
+ ? "Remove from favorites"
+ : "Add to favorites", "Ctrl+F", "favorite");
+ addContextItem(items, "Power-on options" + ELLIPSIS, "Ctrl+P", "override");
+ if(instance().highScores().enabled())
+ addContextItem(items, "High scores" + ELLIPSIS, "Ctrl+H", "highscores");
+ }
}
if(myUseMinimalUI)
addContextItem(items, "Options" + ELLIPSIS, "Ctrl+O", "options");
@@ -1045,7 +1062,7 @@ void LauncherDialog::openContextMenu(int x, int y)
{
addContextItem(items, instance().settings().getBool("launcherextensions")
? "Disable file extensions"
- : "Enable file extensions", "Ctrl+X", "extensions");
+ : "Enable file extensions", "Ctrl+E", "extensions");
if(myList->inVirtualDir())
addContextItem(items, instance().settings().getBool("altsorting")
? "Normal sorting"
diff --git a/src/gui/LauncherFileListWidget.cxx b/src/gui/LauncherFileListWidget.cxx
index bed7ba0f6..5177435b1 100644
--- a/src/gui/LauncherFileListWidget.cxx
+++ b/src/gui/LauncherFileListWidget.cxx
@@ -52,36 +52,25 @@ bool LauncherFileListWidget::isDirectory(const FilesystemNode& node) const
void LauncherFileListWidget::getChildren(const FilesystemNode::CancelCheck& isCancelled)
{
// TODO:
- // + remove virtual folders in virtual folders
- // + tooltips (incl. subdirs)
- // + always add (after remove) recent ROMs
- // + age recently played (e.g. reduce all regularly, WHEN? HOW MUCH?)
- // + mark virtual dir when returning from it
- // + "lastrom"
- // + uppercase search
- // + change sort order
- // + move subdirs & all files into popup menu
- // + no all files option in virtual folders
- // + missing large icons
- // + Settings.cxx doc
- // + display only in ROM path folder
// - remove subdirs & all files from GUI
- // - doc (settings, hotkeys, popup, launcher, virtual folders)
+ // - doc (launcher, virtual directories)
if(_node.exists() || !_node.hasParent())
{
myInVirtualDir = false;
+ myVirtualDir = EmptyString;
FileListWidget::getChildren(isCancelled);
}
else
{
myInVirtualDir = true;
+ myVirtualDir = _node.getName();
+
FilesystemNode parent(_node.getParent());
parent.setName("..");
_fileList.emplace_back(parent);
- const string& name = _node.getName();
- if(name == user_name)
+ if(myVirtualDir == user_name)
{
for(auto& item : myFavorites->userList())
{
@@ -90,7 +79,7 @@ void LauncherFileListWidget::getChildren(const FilesystemNode::CancelCheck& isCa
_fileList.emplace_back(node);
}
}
- else if(name == popular_name)
+ else if(myVirtualDir == popular_name)
{
for(auto& item : myFavorites->popularList())
{
@@ -99,7 +88,7 @@ void LauncherFileListWidget::getChildren(const FilesystemNode::CancelCheck& isCa
_fileList.emplace_back(node);
}
}
- else if(name == recent_name)
+ else if(myVirtualDir == recent_name)
{
for(auto& item : myFavorites->recentList())
{
@@ -187,6 +176,18 @@ void LauncherFileListWidget::toggleUserFavorite()
}
}
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+void LauncherFileListWidget::removeFavorite()
+{
+ if(!selected().isDirectory())
+ {
+ if((inRecentDir() && myFavorites->removeRecent(selected().getPath()))
+ || (inPopularDir() && myFavorites->removePopular(selected().getPath())))
+ // Redraw file list
+ setDirty();
+ }
+}
+
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void LauncherFileListWidget::userFavor(const string& path, bool isUserFavorite)
{
diff --git a/src/gui/LauncherFileListWidget.hxx b/src/gui/LauncherFileListWidget.hxx
index f8ecf35fd..bb8b636d4 100644
--- a/src/gui/LauncherFileListWidget.hxx
+++ b/src/gui/LauncherFileListWidget.hxx
@@ -44,9 +44,13 @@ class LauncherFileListWidget : public FileListWidget
void updateFavorites();
bool isUserFavorite(const string& path) const;
void toggleUserFavorite();
+ void removeFavorite();
bool isDirectory(const FilesystemNode& node) const override;
bool inVirtualDir() const { return myInVirtualDir; }
+ bool inUserDir() const { return myVirtualDir == user_name; }
+ bool inRecentDir() const { return myVirtualDir == recent_name; }
+ bool inPopularDir() const { return myVirtualDir == popular_name; }
private:
static const string user_name;
@@ -55,6 +59,7 @@ class LauncherFileListWidget : public FileListWidget
unique_ptr myFavorites;
bool myInVirtualDir{false};
+ string myVirtualDir;
string myRomDir;
private: