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
This commit is contained in:
Thomas Jentzsch 2021-11-29 09:27:41 +01:00
parent 00609a3a7a
commit 6a67d1c0a9
7 changed files with 157 additions and 68 deletions

View File

@ -307,6 +307,7 @@
TIA sprites and collisions for each object separately</li>
<li>Full system state save/load functionality</li>
<li>Automatic save state creation ('Time Machine') which allows moving back and forth in the recorded timeline</li>
<li>Tracking of user favorites and popular or recently played ROMs.</li>
<li>High scores saving (internal or via PlusROM High Score Club)</li>
<li>Cross-platform UI including a built-in ROM launcher frontend</li>
<li>Built-in extensive debugger, including static analysis with the Distella disassembler
@ -2263,6 +2264,16 @@
<td>Backspace</td>
<td>Backspace</td>
</tr>
<tr>
<td>Remove from 'Recently Played' or 'Most Popular' folder</td>
<td>Control + X</td>
<td>Control + X</td>
</tr>
<tr>
<td>Toggle favorite</td>
<td>Control + F</td>
<td>Control + F</td>
</tr>
<tr>
<td>Open Power-On options dialog</td>
<td>Control + P</td>
@ -2274,20 +2285,25 @@
<td>Control + H</td>
</tr>
<tr>
<td>Toggle favorite</td>
<td>Control + F</td>
<td>Control + F</td>
<td>Toggle file extensions display</td>
<td>Control + E</td>
<td>Control + E</td>
</tr>
<tr>
<td>Toggle show all ROMs</td>
<td>Control + A</td>
<td>Control + A</td>
</tr>
<tr>
<td>Toggle search ROMs in subdirectories too</td>
<td>Control + D</td>
<td>Control + D</td>
</tr>
<tr>
<td>Reload ROM listing</td>
<td>Control + R</td>
<td>Control + R</td>
</tr>
<tr>
<td>Toggle file extensions display</td>
<td>Control + X</td>
<td>Control + X</td>
</tr>
</table>
<p><b>UI Keys in Text Editing areas (cannot be remapped)</b></p>
@ -3250,6 +3266,16 @@
directory only or all subdirectories too.</td>
</tr>
<tr>
<td><pre>-altsorting &lt;1|0&gt;</pre></td>
<td>Alternative sorting in virtual folders.</td>
</tr>
<tr>
<td><pre>-maxrecentroms &lt;1|0&gt;</pre></td>
<td>Number of ROMs tracked in 'Recently played' folder.</td>
</tr>
<tr>
<td><pre>-romviewer &lt;float&gt;</pre></td>
<td>Hide ROM Info Viewer in ROM launcher mode (0) or use the
@ -4210,12 +4236,21 @@
<h3><b><a name="ROMLauncherContextMenu">ROM Launcher Context Menu</a></b></h3>
<p>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:</p>
<p>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:</p>
<p><ol>
<li><p><b><a name="PowerOn">Power-on options</a></b>: Selecting this option shows a dialog whereby
<p><ul>
<li>
<p><b>Remove from recently played/most popular</b> (or 'Control + X'):
This option removes the selected ROM from the current folder.</p>
</li>
<li>
<p><b>Add to/remove from favorites</b> (or 'Control + F'): This option
toggles the favorite state of the selected ROM.</p>
</li>
<li><p><b><a name="PowerOn">Power-on options</a></b> (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 <b>Defaults</b> will disable
@ -4243,16 +4278,33 @@
</td>
</tr>
</table>
<p>This dialog can also be opened by pressing 'Control + P'.</p>
</li>
<li><b>High scores</b>: This option displays the <a href="#HighScores">
High Scores</a> dialog for the selected ROM. Only available if high score
properties have been setup for the ROM. Also available via 'Control + H' keys combo.</li>
<li>
<p><b>High scores</b> (or 'Control + H'): This option displays the <a href="#HighScores">
High Scores</a> dialog for the selected ROM. Only available if high score
properties have been setup for the ROM.</p>
</li>
<br><li><b>Reload listing</b>: Selecting this performs a reload of the
current listing. It is an alternative to pressing the 'Control + R'
key combo.</li>
</ol></p>
<li>
<p><b>Enable/disable file extensions</b> (or 'Control + E'): Toggles the
display of the file extensions.</p>
</li>
<li>
<p><b>Toggle alternative sorting</b> (or 'Control + S'): Toggles
alternative sorting in the virtual directories.</p>
</li>
<li>
<p><b>Show all files/only ROMs</b> (or 'Control + A'): Toggles display of
non-ROM files.</p>
</li>
<li>
<p><b>Include/exclude subdirectories</b> (or 'Control + D'): Toggles searching
of ROMs in current directory only or all subdirectories too.</p>
</li>
<li>
<p><b>Reload listing</b> (or 'Control + R'): Selecting this performs a
reload of the current listing. </p>
</li>
</ul></p>
</blockquote></br>
<h2><b><a name="ROMAudit">ROM Audit Mode</a></b></h2>

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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"

View File

@ -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)
{

View File

@ -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<FavoritesManager> myFavorites;
bool myInVirtualDir{false};
string myVirtualDir;
string myRomDir;
private: