mirror of https://github.com/stella-emu/stella.git
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:
parent
00609a3a7a
commit
6a67d1c0a9
|
@ -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 <1|0></pre></td>
|
||||
<td>Alternative sorting in virtual folders.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><pre>-maxrecentroms <1|0></pre></td>
|
||||
<td>Number of ROMs tracked in 'Recently played' folder.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><pre>-romviewer <float></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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue