First pass at converting LauncherDialog to use FileListWidget, similar to BrowserDialog.

- FileListWidget is a newer development, and LauncherDialog duplicates some (but not all) of its functionality
- Similarly, BrowserDialog has some functionality that LauncherDialog does not
- We will implement all required functionality in FileListWidget, and have both classes use it.

BrowserDialog is currently slightly broken; not all functionality is reimplemented yet.
This commit is contained in:
Stephen Anthony 2019-06-21 14:51:55 -02:30
parent d7e9c95fb0
commit 786f3b2a49
4 changed files with 139 additions and 138 deletions

View File

@ -18,6 +18,8 @@
#include "ScrollBarWidget.hxx"
#include "FileListWidget.hxx"
#include "Bankswitch.hxx"
#include "MD5.hxx"
#include "bspf.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -25,7 +27,7 @@ FileListWidget::FileListWidget(GuiObject* boss, const GUI::Font& font,
int x, int y, int w, int h)
: StringListWidget(boss, font, x, y, w, h),
_fsmode(FilesystemNode::ListMode::All),
_extension("")
_selectedPos(0)
{
// This widget is special, in that it catches signals and redirects them
setTarget(this);
@ -90,6 +92,26 @@ void FileListWidget::selectParent()
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FileListWidget::reload()
{
if(_node.exists())
setLocation(_node, _gameList.name(_selectedPos));
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const string& FileListWidget::selectedMD5()
{
if(_selected.isDirectory() || !Bankswitch::isValidRomName(_selected))
return EmptyString;
// Make sure we have a valid md5 for this ROM
if(_gameList.md5(_selectedPos) == "")
_gameList.setMd5(_selectedPos, MD5::hash(_selected));
return _gameList.md5(_selectedPos);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FileListWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
{
@ -102,6 +124,7 @@ void FileListWidget::handleCommand(CommandSender* sender, int cmd, int data, int
case ListWidget::kSelectionChangedCmd:
cmd = ItemChanged;
_selected = FilesystemNode(_gameList.path(data));
_selectedPos = data;
break;
case ListWidget::kActivatedCmd:
@ -116,7 +139,6 @@ void FileListWidget::handleCommand(CommandSender* sender, int cmd, int data, int
}
else
cmd = ItemActivated;
break;
default:

View File

@ -35,7 +35,7 @@ class CommandSender;
Note that for the current implementation, the ItemActivated signal is
not sent when activating a directory (instead the code descends into
the directory). This may be changed in a future revision.
the directory).
*/
class FileListWidget : public StringListWidget
{
@ -60,20 +60,31 @@ class FileListWidget : public StringListWidget
/** Select parent directory (if applicable) */
void selectParent();
/** Reload current location (file or directory) */
void reload();
/** Gets current node(s) */
const FilesystemNode& selected() const { return _selected; }
const FilesystemNode& currentDir() const { return _node; }
protected:
/** Gets MD5sum of the current node, if it is a file, and caches the result.
Otherwise, does nothing.
@return MD5sum of selected file, else EmptyString
*/
const string& selectedMD5();
private:
void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
private:
FilesystemNode::ListMode _fsmode;
FilesystemNode _node, _selected;
string _extension;
GameList _gameList;
string _extension;
uInt32 _selectedPos;
private:
// Following constructors and assignment operators not supported
FileListWidget() = delete;

View File

@ -16,15 +16,14 @@
//============================================================================
#include "bspf.hxx"
#include "Bankswitch.hxx"
#include "BrowserDialog.hxx"
#include "ContextMenu.hxx"
#include "DialogContainer.hxx"
#include "Dialog.hxx"
#include "EditTextWidget.hxx"
#include "FileListWidget.hxx"
#include "FSNode.hxx"
#include "GameList.hxx"
#include "MD5.hxx"
#include "OptionsDialog.hxx"
#include "GlobalPropsDialog.hxx"
#include "StellaSettingsDialog.hxx"
@ -38,12 +37,18 @@
#include "PropsSet.hxx"
#include "RomInfoWidget.hxx"
#include "Settings.hxx"
#include "StringListWidget.hxx"
#include "Widget.hxx"
#include "Font.hxx"
#include "Version.hxx"
#include "LauncherDialog.hxx"
/**
TODO:
- show all files / only ROMs
- connect to 'matchPattern'
- history of selected folders/files
*/
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent,
int x, int y, int w, int h)
@ -142,9 +147,10 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent,
romWidth = 365;
int listWidth = _w - (romWidth > 0 ? romWidth+8 : 0) - 20;
myList = new StringListWidget(this, font, xpos, ypos,
myList = new FileListWidget(this, font, xpos, ypos,
listWidth, _h - 43 - bheight - fontHeight - lineHeight);
myList->setEditable(false);
myList->setFileListMode(FilesystemNode::ListMode::All);
wid.push_back(myList);
// Add ROM info area (if enabled)
@ -211,10 +217,6 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent,
else
mySelectedItem = 2;
// Create a game list, which contains all the information about a ROM that
// the launcher needs
myGameList = make_unique<GameList>();
addToFocusList(wid);
// Create context menu for ROM list options
@ -236,31 +238,27 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent,
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const string& LauncherDialog::selectedRom()
const string& LauncherDialog::selectedRom() const
{
int item = myList->getSelected();
if(item < 0)
return EmptyString;
return myGameList->path(item);
return currentNode().getPath();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const string& LauncherDialog::selectedRomMD5()
{
int item = myList->getSelected();
if(item < 0)
return EmptyString;
return myList->selectedMD5();
}
const FilesystemNode node(myGameList->path(item));
if(node.isDirectory() || !Bankswitch::isValidRomName(node))
return EmptyString;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const FilesystemNode& LauncherDialog::currentNode() const
{
return myList->selected();
}
// Make sure we have a valid md5 for this ROM
if(myGameList->md5(item) == "")
myGameList->setMd5(item, MD5::hash(node));
return myGameList->md5(item);
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void LauncherDialog::reload()
{
myList->reload();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -276,26 +274,43 @@ void LauncherDialog::loadConfig()
// has been called (and we should reload the list)
if(myList->getList().empty())
{
if(myPrevDirButton)
myPrevDirButton->setEnabled(false);
myCurrentNode = FilesystemNode(romdir == "" ? "~" : romdir);
if(!(myCurrentNode.exists() && myCurrentNode.isDirectory()))
myCurrentNode = FilesystemNode("~");
FilesystemNode node(romdir == "" ? "~" : romdir);
if(!(node.exists() && node.isDirectory()))
node = FilesystemNode("~");
updateListing();
myList->setLocation(node);
updateUI(instance().settings().getString("lastrom"));
}
Dialog::setFocus(getFocusList()[mySelectedItem]);
if(myRomInfoWidget)
{
int item = myList->getSelected();
if(item < 0) return;
const FilesystemNode node(myGameList->path(item));
myRomInfoWidget->reloadProperties(node);
}
myRomInfoWidget->reloadProperties(currentNode());
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void LauncherDialog::updateUI(const string& nameToSelect)
{
// Only hilite the 'up' button if there's a parent directory
if(myPrevDirButton)
myPrevDirButton->setEnabled(myList->currentDir().hasParent());
// Show current directory
myDir->setText(myList->currentDir().getShortPath());
// Indicate how many files were found
ostringstream buf;
buf << (myList->getList().size() - 1) << " items found";
myRomCount->setLabel(buf.str());
// Restore last selection
if(nameToSelect != "")
myList->setSelected(nameToSelect);
// Update ROM info UI item
loadRomInfo();
}
#if 0
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void LauncherDialog::updateListing(const string& nameToSelect)
{
@ -365,26 +380,22 @@ void LauncherDialog::loadDirListing()
// Sort the list by rom name (since that's what we see in the listview)
myGameList->sortByName();
}
#endif
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void LauncherDialog::loadRomInfo()
{
if(!myRomInfoWidget) return;
int item = myList->getSelected();
if(item < 0) return;
if(!myRomInfoWidget)
return;
const FilesystemNode node(myGameList->path(item));
if(!node.isDirectory() && Bankswitch::isValidRomName(node))
const string& md5 = selectedRomMD5();
if(md5 != EmptyString)
{
// Make sure we have a valid md5 for this ROM
if(myGameList->md5(item) == "")
myGameList->setMd5(item, MD5::hash(node));
// Get the properties for this entry
Properties props;
instance().propSet().getMD5WithInsert(node, myGameList->md5(item), props);
instance().propSet().getMD5WithInsert(currentNode(), md5, props);
myRomInfoWidget->setProperties(props, node);
myRomInfoWidget->setProperties(props, currentNode());
}
else
myRomInfoWidget->clearProperties();
@ -396,13 +407,9 @@ void LauncherDialog::handleContextMenu()
const string& cmd = myMenu->getSelectedTag().toString();
if(cmd == "override")
{
myGlobalProps->open();
}
else if(cmd == "reload")
{
updateListing();
}
reload();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -459,7 +466,7 @@ void LauncherDialog::handleKeyDown(StellaKey key, StellaMod mod)
// Grab the key before passing it to the actual dialog and check for
// Control-R (reload ROM listing)
if(StellaModTest::isControl(mod) && key == KBDK_R)
updateListing();
reload();
else
#if defined(RETRON77)
// handle keys used by R77
@ -554,14 +561,16 @@ void LauncherDialog::handleCommand(CommandSender* sender, int cmd,
{
case kAllfilesCmd:
showOnlyROMs(myAllFiles ? !myAllFiles->getState() : true);
updateListing();
reload();
break;
case kLoadROMCmd:
case ListWidget::kActivatedCmd:
case ListWidget::kDoubleClickedCmd:
case FileListWidget::ItemActivated:
{
startGame();
if(currentNode().isDirectory())
myList->setLocation(currentNode());
else
loadRom();
break;
}
@ -570,13 +579,11 @@ void LauncherDialog::handleCommand(CommandSender* sender, int cmd,
break;
case kPrevDirCmd:
case ListWidget::kPrevDirCmd:
myCurrentNode = myCurrentNode.getParent();
updateListing(myNodeNames.empty() ? "" : myNodeNames.pop());
myList->selectParent();
break;
case ListWidget::kSelectionChangedCmd:
loadRomInfo();
case FileListWidget::ItemChanged:
updateUI();
break;
case kQuitCmd:
@ -585,72 +592,37 @@ void LauncherDialog::handleCommand(CommandSender* sender, int cmd,
break;
case kRomDirChosenCmd:
myCurrentNode = FilesystemNode(instance().settings().getString("romdir"));
if(!(myCurrentNode.exists() && myCurrentNode.isDirectory()))
myCurrentNode = FilesystemNode("~");
updateListing();
break;
case kReloadRomDirCmd:
updateListing();
{
FilesystemNode node(instance().settings().getString("romdir"));
if(!(node.exists() && node.isDirectory()))
node = FilesystemNode("~");
myList->setLocation(node);
break;
}
case ContextMenu::kItemSelectedCmd:
handleContextMenu();
break;
case EditableWidget::kAcceptCmd:
case EditableWidget::kChangedCmd:
// The updateListing() method knows what to do when the text changes
updateListing();
break;
default:
Dialog::handleCommand(sender, cmd, data, 0);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void LauncherDialog::startGame()
void LauncherDialog::loadRom()
{
int item = myList->getSelected();
if(item >= 0)
{
const FilesystemNode romnode(myGameList->path(item));
// Directory's should be selected (ie, enter them and redisplay)
if(romnode.isDirectory())
{
string dirname = "";
if(myGameList->name(item) == " [..]")
{
myCurrentNode = myCurrentNode.getParent();
if(!myNodeNames.empty())
dirname = myNodeNames.pop();
}
else
{
myCurrentNode = romnode;
myNodeNames.push(myGameList->name(item));
}
updateListing(dirname);
}
else
{
const string& result =
instance().createConsole(romnode, myGameList->md5(item));
const string& result = instance().createConsole(currentNode(), myList->selectedMD5());
if(result == EmptyString)
{
instance().settings().setValue("lastrom", myList->getSelectedString());
// If romdir has never been set, set it now based on the selected rom
if(instance().settings().getString("romdir") == EmptyString)
instance().settings().setValue("romdir", romnode.getParent().getShortPath());
instance().settings().setValue("romdir", currentNode().getParent().getShortPath());
}
else
instance().frameBuffer().showMessage(result, MessagePosition::MiddleCenter, true);
}
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -22,7 +22,6 @@ class ButtonWidget;
class CommandSender;
class ContextMenu;
class DialogContainer;
class GameList;
class BrowserDialog;
class OptionsDialog;
class GlobalPropsDialog;
@ -30,9 +29,9 @@ class StellaSettingsDialog;
class OSystem;
class Properties;
class EditTextWidget;
class FileListWidget;
class RomInfoWidget;
class StaticTextWidget;
class StringListWidget;
namespace GUI {
class MessageBox;
}
@ -49,8 +48,7 @@ class LauncherDialog : public Dialog
enum {
kAllfilesCmd = 'lalf', // show all files (or ROMs only)
kLoadROMCmd = 'STRT', // load currently selected ROM
kRomDirChosenCmd = 'romc', // rom dir chosen
kReloadRomDirCmd = 'rdrl', // reload the current listing
kRomDirChosenCmd = 'romc' // rom dir chosen
};
public:
@ -59,30 +57,32 @@ class LauncherDialog : public Dialog
virtual ~LauncherDialog() = default;
/**
Get path for the currently selected file
Get path for the currently selected file.
@return path if a valid ROM file, else the empty string
*/
const string& selectedRom();
const string& selectedRom() const;
/**
Get MD5sum for the currently selected file
Get MD5sum for the currently selected file.
If the MD5 hasn't already been calculated, it will be
calculated (and cached) for future use.
@return md5sum if a valid ROM file, else the empty string
*/
const string& selectedRomMD5();
/**
Get node for the currently selected directory
Get node for the currently selected directory.
@return FilesystemNode currently active
*/
const FilesystemNode& currentNode() const { return myCurrentNode; }
const FilesystemNode& currentNode() const;
/**
Reload the current listing
*/
void reload() { updateListing(); }
void reload();
private:
void center() override { positionAt(0); }
@ -93,20 +93,18 @@ class LauncherDialog : public Dialog
Event::Type getJoyAxisEvent(int stick, int axis, int value) override;
void loadConfig() override;
void updateListing(const string& nameToSelect = "");
void updateUI(const string& nameToSelect = "");
void loadDirListing();
void loadRom();
void loadRomInfo();
void handleContextMenu();
void showOnlyROMs(bool state);
bool matchPattern(const string& s, const string& pattern) const;
void startGame();
void openSettings();
private:
unique_ptr<OptionsDialog> myOptionsDialog;
unique_ptr<StellaSettingsDialog> myStellaSettingsDialog;
unique_ptr<GameList> myGameList;
unique_ptr<ContextMenu> myMenu;
unique_ptr<GlobalPropsDialog> myGlobalProps;
unique_ptr<BrowserDialog> myRomDir;
@ -116,7 +114,7 @@ class LauncherDialog : public Dialog
ButtonWidget* myOptionsButton;
ButtonWidget* myQuitButton;
StringListWidget* myList;
FileListWidget* myList;
StaticTextWidget* myDirLabel;
EditTextWidget* myDir;
StaticTextWidget* myRomCount;
@ -126,8 +124,6 @@ class LauncherDialog : public Dialog
RomInfoWidget* myRomInfoWidget;
int mySelectedItem;
FilesystemNode myCurrentNode;
Common::FixedStack<string> myNodeNames;
bool myShowOnlyROMs;
bool myUseMinimalUI;